blob: 6f1b366aa307ec597537895782c4b9296d12de67 [file] [log] [blame]
Guy Benyei11169dd2012-12-18 14:30:41 +00001//===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the main API hooks in the Clang-C Source Indexing
11// library.
12//
13//===----------------------------------------------------------------------===//
14
15#include "CIndexer.h"
16#include "CIndexDiagnostic.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000017#include "CLog.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000018#include "CXCursor.h"
19#include "CXSourceLocation.h"
20#include "CXString.h"
21#include "CXTranslationUnit.h"
22#include "CXType.h"
23#include "CursorVisitor.h"
David Blaikie0a4e61f2013-09-13 18:32:52 +000024#include "clang/AST/Attr.h"
Eli Bendersky44a206f2014-07-31 18:04:56 +000025#include "clang/AST/Mangle.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000026#include "clang/AST/StmtVisitor.h"
27#include "clang/Basic/Diagnostic.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000028#include "clang/Basic/DiagnosticCategories.h"
29#include "clang/Basic/DiagnosticIDs.h"
Eli Bendersky79759592014-08-01 15:01:10 +000030#include "clang/Basic/TargetInfo.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000031#include "clang/Basic/Version.h"
32#include "clang/Frontend/ASTUnit.h"
33#include "clang/Frontend/CompilerInstance.h"
34#include "clang/Frontend/FrontendDiagnostic.h"
Dmitri Gribenko9e605112013-11-13 22:16:51 +000035#include "clang/Index/CommentToXML.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000036#include "clang/Lex/HeaderSearch.h"
37#include "clang/Lex/Lexer.h"
38#include "clang/Lex/PreprocessingRecord.h"
39#include "clang/Lex/Preprocessor.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000040#include "clang/Serialization/SerializationDiagnostic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000041#include "llvm/ADT/Optional.h"
42#include "llvm/ADT/STLExtras.h"
43#include "llvm/ADT/StringSwitch.h"
Alp Toker1d257e12014-06-04 03:28:55 +000044#include "llvm/Config/llvm-config.h"
Eli Bendersky79759592014-08-01 15:01:10 +000045#include "llvm/IR/DataLayout.h"
46#include "llvm/IR/Mangler.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000047#include "llvm/Support/Compiler.h"
48#include "llvm/Support/CrashRecoveryContext.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000049#include "llvm/Support/Format.h"
Chandler Carruth37ad2582014-06-27 15:14:39 +000050#include "llvm/Support/ManagedStatic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000051#include "llvm/Support/MemoryBuffer.h"
52#include "llvm/Support/Mutex.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000053#include "llvm/Support/Program.h"
54#include "llvm/Support/SaveAndRestore.h"
55#include "llvm/Support/Signals.h"
Adrian Prantlbc068582015-07-08 01:00:30 +000056#include "llvm/Support/TargetSelect.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000057#include "llvm/Support/Threading.h"
58#include "llvm/Support/Timer.h"
59#include "llvm/Support/raw_ostream.h"
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000060
Alp Toker1a86ad22014-07-06 06:24:00 +000061#if LLVM_ENABLE_THREADS != 0 && defined(__APPLE__)
62#define USE_DARWIN_THREADS
63#endif
64
65#ifdef USE_DARWIN_THREADS
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000066#include <pthread.h>
67#endif
Guy Benyei11169dd2012-12-18 14:30:41 +000068
69using namespace clang;
70using namespace clang::cxcursor;
Guy Benyei11169dd2012-12-18 14:30:41 +000071using namespace clang::cxtu;
72using namespace clang::cxindex;
73
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000074CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) {
75 if (!AU)
Craig Topper69186e72014-06-08 08:38:04 +000076 return nullptr;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000077 assert(CIdx);
Guy Benyei11169dd2012-12-18 14:30:41 +000078 CXTranslationUnit D = new CXTranslationUnitImpl();
79 D->CIdx = CIdx;
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000080 D->TheASTUnit = AU;
Dmitri Gribenko74895212013-02-03 13:52:47 +000081 D->StringPool = new cxstring::CXStringPool();
Craig Topper69186e72014-06-08 08:38:04 +000082 D->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000083 D->OverridenCursorsPool = createOverridenCXCursorsPool();
Craig Topper69186e72014-06-08 08:38:04 +000084 D->CommentToXML = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000085 return D;
86}
87
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000088bool cxtu::isASTReadError(ASTUnit *AU) {
89 for (ASTUnit::stored_diag_iterator D = AU->stored_diag_begin(),
90 DEnd = AU->stored_diag_end();
91 D != DEnd; ++D) {
92 if (D->getLevel() >= DiagnosticsEngine::Error &&
93 DiagnosticIDs::getCategoryNumberForDiag(D->getID()) ==
94 diag::DiagCat_AST_Deserialization_Issue)
95 return true;
96 }
97 return false;
98}
99
Guy Benyei11169dd2012-12-18 14:30:41 +0000100cxtu::CXTUOwner::~CXTUOwner() {
101 if (TU)
102 clang_disposeTranslationUnit(TU);
103}
104
105/// \brief Compare two source ranges to determine their relative position in
106/// the translation unit.
107static RangeComparisonResult RangeCompare(SourceManager &SM,
108 SourceRange R1,
109 SourceRange R2) {
110 assert(R1.isValid() && "First range is invalid?");
111 assert(R2.isValid() && "Second range is invalid?");
112 if (R1.getEnd() != R2.getBegin() &&
113 SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
114 return RangeBefore;
115 if (R2.getEnd() != R1.getBegin() &&
116 SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
117 return RangeAfter;
118 return RangeOverlap;
119}
120
121/// \brief Determine if a source location falls within, before, or after a
122/// a given source range.
123static RangeComparisonResult LocationCompare(SourceManager &SM,
124 SourceLocation L, SourceRange R) {
125 assert(R.isValid() && "First range is invalid?");
126 assert(L.isValid() && "Second range is invalid?");
127 if (L == R.getBegin() || L == R.getEnd())
128 return RangeOverlap;
129 if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
130 return RangeBefore;
131 if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
132 return RangeAfter;
133 return RangeOverlap;
134}
135
136/// \brief Translate a Clang source range into a CIndex source range.
137///
138/// Clang internally represents ranges where the end location points to the
139/// start of the token at the end. However, for external clients it is more
140/// useful to have a CXSourceRange be a proper half-open interval. This routine
141/// does the appropriate translation.
142CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
143 const LangOptions &LangOpts,
144 const CharSourceRange &R) {
145 // We want the last character in this location, so we will adjust the
146 // location accordingly.
147 SourceLocation EndLoc = R.getEnd();
148 if (EndLoc.isValid() && EndLoc.isMacroID() && !SM.isMacroArgExpansion(EndLoc))
149 EndLoc = SM.getExpansionRange(EndLoc).second;
Yaron Keren8b563662015-10-03 10:46:20 +0000150 if (R.isTokenRange() && EndLoc.isValid()) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000151 unsigned Length = Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc),
152 SM, LangOpts);
153 EndLoc = EndLoc.getLocWithOffset(Length);
154 }
155
Bill Wendlingeade3622013-01-23 08:25:41 +0000156 CXSourceRange Result = {
Dmitri Gribenkof9304482013-01-23 15:56:07 +0000157 { &SM, &LangOpts },
Bill Wendlingeade3622013-01-23 08:25:41 +0000158 R.getBegin().getRawEncoding(),
159 EndLoc.getRawEncoding()
160 };
Guy Benyei11169dd2012-12-18 14:30:41 +0000161 return Result;
162}
163
164//===----------------------------------------------------------------------===//
165// Cursor visitor.
166//===----------------------------------------------------------------------===//
167
168static SourceRange getRawCursorExtent(CXCursor C);
169static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
170
171
172RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
173 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
174}
175
176/// \brief Visit the given cursor and, if requested by the visitor,
177/// its children.
178///
179/// \param Cursor the cursor to visit.
180///
181/// \param CheckedRegionOfInterest if true, then the caller already checked
182/// that this cursor is within the region of interest.
183///
184/// \returns true if the visitation should be aborted, false if it
185/// should continue.
186bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
187 if (clang_isInvalid(Cursor.kind))
188 return false;
189
190 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000191 const Decl *D = getCursorDecl(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000192 if (!D) {
193 assert(0 && "Invalid declaration cursor");
194 return true; // abort.
195 }
196
197 // Ignore implicit declarations, unless it's an objc method because
198 // currently we should report implicit methods for properties when indexing.
199 if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
200 return false;
201 }
202
203 // If we have a range of interest, and this cursor doesn't intersect with it,
204 // we're done.
205 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
206 SourceRange Range = getRawCursorExtent(Cursor);
207 if (Range.isInvalid() || CompareRegionOfInterest(Range))
208 return false;
209 }
210
211 switch (Visitor(Cursor, Parent, ClientData)) {
212 case CXChildVisit_Break:
213 return true;
214
215 case CXChildVisit_Continue:
216 return false;
217
218 case CXChildVisit_Recurse: {
219 bool ret = VisitChildren(Cursor);
220 if (PostChildrenVisitor)
221 if (PostChildrenVisitor(Cursor, ClientData))
222 return true;
223 return ret;
224 }
225 }
226
227 llvm_unreachable("Invalid CXChildVisitResult!");
228}
229
230static bool visitPreprocessedEntitiesInRange(SourceRange R,
231 PreprocessingRecord &PPRec,
232 CursorVisitor &Visitor) {
233 SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
234 FileID FID;
235
236 if (!Visitor.shouldVisitIncludedEntities()) {
237 // If the begin/end of the range lie in the same FileID, do the optimization
238 // where we skip preprocessed entities that do not come from the same FileID.
239 FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
240 if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
241 FID = FileID();
242 }
243
Benjamin Kramerb4ef6682015-02-06 17:25:10 +0000244 const auto &Entities = PPRec.getPreprocessedEntitiesInRange(R);
245 return Visitor.visitPreprocessedEntities(Entities.begin(), Entities.end(),
Guy Benyei11169dd2012-12-18 14:30:41 +0000246 PPRec, FID);
247}
248
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000249bool CursorVisitor::visitFileRegion() {
Guy Benyei11169dd2012-12-18 14:30:41 +0000250 if (RegionOfInterest.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000251 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000252
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000253 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000254 SourceManager &SM = Unit->getSourceManager();
255
256 std::pair<FileID, unsigned>
257 Begin = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getBegin())),
258 End = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getEnd()));
259
260 if (End.first != Begin.first) {
261 // If the end does not reside in the same file, try to recover by
262 // picking the end of the file of begin location.
263 End.first = Begin.first;
264 End.second = SM.getFileIDSize(Begin.first);
265 }
266
267 assert(Begin.first == End.first);
268 if (Begin.second > End.second)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000269 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000270
271 FileID File = Begin.first;
272 unsigned Offset = Begin.second;
273 unsigned Length = End.second - Begin.second;
274
275 if (!VisitDeclsOnly && !VisitPreprocessorLast)
276 if (visitPreprocessedEntitiesInRegion())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000277 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000278
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000279 if (visitDeclsFromFileRegion(File, Offset, Length))
280 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000281
282 if (!VisitDeclsOnly && VisitPreprocessorLast)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000283 return visitPreprocessedEntitiesInRegion();
284
285 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000286}
287
288static bool isInLexicalContext(Decl *D, DeclContext *DC) {
289 if (!DC)
290 return false;
291
292 for (DeclContext *DeclDC = D->getLexicalDeclContext();
293 DeclDC; DeclDC = DeclDC->getLexicalParent()) {
294 if (DeclDC == DC)
295 return true;
296 }
297 return false;
298}
299
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000300bool CursorVisitor::visitDeclsFromFileRegion(FileID File,
Guy Benyei11169dd2012-12-18 14:30:41 +0000301 unsigned Offset, unsigned Length) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000302 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000303 SourceManager &SM = Unit->getSourceManager();
304 SourceRange Range = RegionOfInterest;
305
306 SmallVector<Decl *, 16> Decls;
307 Unit->findFileRegionDecls(File, Offset, Length, Decls);
308
309 // If we didn't find any file level decls for the file, try looking at the
310 // file that it was included from.
311 while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
312 bool Invalid = false;
313 const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
314 if (Invalid)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000315 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000316
317 SourceLocation Outer;
318 if (SLEntry.isFile())
319 Outer = SLEntry.getFile().getIncludeLoc();
320 else
321 Outer = SLEntry.getExpansion().getExpansionLocStart();
322 if (Outer.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000323 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000324
Benjamin Kramer867ea1d2014-03-02 13:01:17 +0000325 std::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
Guy Benyei11169dd2012-12-18 14:30:41 +0000326 Length = 0;
327 Unit->findFileRegionDecls(File, Offset, Length, Decls);
328 }
329
330 assert(!Decls.empty());
331
332 bool VisitedAtLeastOnce = false;
Craig Topper69186e72014-06-08 08:38:04 +0000333 DeclContext *CurDC = nullptr;
Craig Topper2341c0d2013-07-04 03:08:24 +0000334 SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
335 for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000336 Decl *D = *DIt;
337 if (D->getSourceRange().isInvalid())
338 continue;
339
340 if (isInLexicalContext(D, CurDC))
341 continue;
342
343 CurDC = dyn_cast<DeclContext>(D);
344
345 if (TagDecl *TD = dyn_cast<TagDecl>(D))
346 if (!TD->isFreeStanding())
347 continue;
348
349 RangeComparisonResult CompRes = RangeCompare(SM, D->getSourceRange(),Range);
350 if (CompRes == RangeBefore)
351 continue;
352 if (CompRes == RangeAfter)
353 break;
354
355 assert(CompRes == RangeOverlap);
356 VisitedAtLeastOnce = true;
357
358 if (isa<ObjCContainerDecl>(D)) {
359 FileDI_current = &DIt;
360 FileDE_current = DE;
361 } else {
Craig Topper69186e72014-06-08 08:38:04 +0000362 FileDI_current = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +0000363 }
364
365 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000366 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000367 }
368
369 if (VisitedAtLeastOnce)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000370 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000371
372 // No Decls overlapped with the range. Move up the lexical context until there
373 // is a context that contains the range or we reach the translation unit
374 // level.
375 DeclContext *DC = DIt == Decls.begin() ? (*DIt)->getLexicalDeclContext()
376 : (*(DIt-1))->getLexicalDeclContext();
377
378 while (DC && !DC->isTranslationUnit()) {
379 Decl *D = cast<Decl>(DC);
380 SourceRange CurDeclRange = D->getSourceRange();
381 if (CurDeclRange.isInvalid())
382 break;
383
384 if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000385 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
386 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000387 }
388
389 DC = D->getLexicalDeclContext();
390 }
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000391
392 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000393}
394
395bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
396 if (!AU->getPreprocessor().getPreprocessingRecord())
397 return false;
398
399 PreprocessingRecord &PPRec
400 = *AU->getPreprocessor().getPreprocessingRecord();
401 SourceManager &SM = AU->getSourceManager();
402
403 if (RegionOfInterest.isValid()) {
404 SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
405 SourceLocation B = MappedRange.getBegin();
406 SourceLocation E = MappedRange.getEnd();
407
408 if (AU->isInPreambleFileID(B)) {
409 if (SM.isLoadedSourceLocation(E))
410 return visitPreprocessedEntitiesInRange(SourceRange(B, E),
411 PPRec, *this);
412
413 // Beginning of range lies in the preamble but it also extends beyond
414 // it into the main file. Split the range into 2 parts, one covering
415 // the preamble and another covering the main file. This allows subsequent
416 // calls to visitPreprocessedEntitiesInRange to accept a source range that
417 // lies in the same FileID, allowing it to skip preprocessed entities that
418 // do not come from the same FileID.
419 bool breaked =
420 visitPreprocessedEntitiesInRange(
421 SourceRange(B, AU->getEndOfPreambleFileID()),
422 PPRec, *this);
423 if (breaked) return true;
424 return visitPreprocessedEntitiesInRange(
425 SourceRange(AU->getStartOfMainFileID(), E),
426 PPRec, *this);
427 }
428
429 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
430 }
431
432 bool OnlyLocalDecls
433 = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
434
435 if (OnlyLocalDecls)
436 return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
437 PPRec);
438
439 return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
440}
441
442template<typename InputIterator>
443bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
444 InputIterator Last,
445 PreprocessingRecord &PPRec,
446 FileID FID) {
447 for (; First != Last; ++First) {
448 if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
449 continue;
450
451 PreprocessedEntity *PPE = *First;
Argyrios Kyrtzidis1030f262013-05-07 20:37:17 +0000452 if (!PPE)
453 continue;
454
Guy Benyei11169dd2012-12-18 14:30:41 +0000455 if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
456 if (Visit(MakeMacroExpansionCursor(ME, TU)))
457 return true;
Richard Smith66a81862015-05-04 02:25:31 +0000458
Guy Benyei11169dd2012-12-18 14:30:41 +0000459 continue;
460 }
Richard Smith66a81862015-05-04 02:25:31 +0000461
462 if (MacroDefinitionRecord *MD = dyn_cast<MacroDefinitionRecord>(PPE)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000463 if (Visit(MakeMacroDefinitionCursor(MD, TU)))
464 return true;
Richard Smith66a81862015-05-04 02:25:31 +0000465
Guy Benyei11169dd2012-12-18 14:30:41 +0000466 continue;
467 }
468
469 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
470 if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
471 return true;
472
473 continue;
474 }
475 }
476
477 return false;
478}
479
480/// \brief Visit the children of the given cursor.
481///
482/// \returns true if the visitation should be aborted, false if it
483/// should continue.
484bool CursorVisitor::VisitChildren(CXCursor Cursor) {
485 if (clang_isReference(Cursor.kind) &&
486 Cursor.kind != CXCursor_CXXBaseSpecifier) {
487 // By definition, references have no children.
488 return false;
489 }
490
491 // Set the Parent field to Cursor, then back to its old value once we're
492 // done.
493 SetParentRAII SetParent(Parent, StmtParent, Cursor);
494
495 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000496 Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +0000497 if (!D)
498 return false;
499
500 return VisitAttributes(D) || Visit(D);
501 }
502
503 if (clang_isStatement(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000504 if (const Stmt *S = getCursorStmt(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000505 return Visit(S);
506
507 return false;
508 }
509
510 if (clang_isExpression(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000511 if (const Expr *E = getCursorExpr(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000512 return Visit(E);
513
514 return false;
515 }
516
517 if (clang_isTranslationUnit(Cursor.kind)) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000518 CXTranslationUnit TU = getCursorTU(Cursor);
519 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000520
521 int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
522 for (unsigned I = 0; I != 2; ++I) {
523 if (VisitOrder[I]) {
524 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
525 RegionOfInterest.isInvalid()) {
526 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
527 TLEnd = CXXUnit->top_level_end();
528 TL != TLEnd; ++TL) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000529 if (Visit(MakeCXCursor(*TL, TU, RegionOfInterest), true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000530 return true;
531 }
532 } else if (VisitDeclContext(
533 CXXUnit->getASTContext().getTranslationUnitDecl()))
534 return true;
535 continue;
536 }
537
538 // Walk the preprocessing record.
539 if (CXXUnit->getPreprocessor().getPreprocessingRecord())
540 visitPreprocessedEntitiesInRegion();
541 }
542
543 return false;
544 }
545
546 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000547 if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000548 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
549 return Visit(BaseTSInfo->getTypeLoc());
550 }
551 }
552 }
553
554 if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +0000555 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +0000556 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
Richard Smithb1f9a282013-10-31 01:56:18 +0000557 if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())
Richard Smithb87c4652013-10-31 21:23:20 +0000558 return Visit(cxcursor::MakeCursorObjCClassRef(
559 ObjT->getInterface(),
560 A->getInterfaceLoc()->getTypeLoc().getLocStart(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +0000561 }
562
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000563 // If pointing inside a macro definition, check if the token is an identifier
564 // that was ever defined as a macro. In such a case, create a "pseudo" macro
565 // expansion cursor for that token.
566 SourceLocation BeginLoc = RegionOfInterest.getBegin();
567 if (Cursor.kind == CXCursor_MacroDefinition &&
568 BeginLoc == RegionOfInterest.getEnd()) {
569 SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000570 const MacroInfo *MI =
571 getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
Richard Smith66a81862015-05-04 02:25:31 +0000572 if (MacroDefinitionRecord *MacroDef =
573 checkForMacroInMacroDefinition(MI, Loc, TU))
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000574 return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
575 }
576
Guy Benyei11169dd2012-12-18 14:30:41 +0000577 // Nothing to visit at the moment.
578 return false;
579}
580
581bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
582 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
583 if (Visit(TSInfo->getTypeLoc()))
584 return true;
585
586 if (Stmt *Body = B->getBody())
587 return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
588
589 return false;
590}
591
Ted Kremenek03325582013-02-21 01:29:01 +0000592Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000593 if (RegionOfInterest.isValid()) {
594 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
595 if (Range.isInvalid())
David Blaikie7a30dc52013-02-21 01:47:18 +0000596 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000597
598 switch (CompareRegionOfInterest(Range)) {
599 case RangeBefore:
600 // This declaration comes before the region of interest; skip it.
David Blaikie7a30dc52013-02-21 01:47:18 +0000601 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000602
603 case RangeAfter:
604 // This declaration comes after the region of interest; we're done.
605 return false;
606
607 case RangeOverlap:
608 // This declaration overlaps the region of interest; visit it.
609 break;
610 }
611 }
612 return true;
613}
614
615bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
616 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
617
618 // FIXME: Eventually remove. This part of a hack to support proper
619 // iteration over all Decls contained lexically within an ObjC container.
620 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
621 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
622
623 for ( ; I != E; ++I) {
624 Decl *D = *I;
625 if (D->getLexicalDeclContext() != DC)
626 continue;
627 CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
628
629 // Ignore synthesized ivars here, otherwise if we have something like:
630 // @synthesize prop = _prop;
631 // and '_prop' is not declared, we will encounter a '_prop' ivar before
632 // encountering the 'prop' synthesize declaration and we will think that
633 // we passed the region-of-interest.
634 if (ObjCIvarDecl *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
635 if (ivarD->getSynthesize())
636 continue;
637 }
638
639 // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
640 // declarations is a mismatch with the compiler semantics.
641 if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
642 ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
643 if (!ID->isThisDeclarationADefinition())
644 Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
645
646 } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
647 ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
648 if (!PD->isThisDeclarationADefinition())
649 Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
650 }
651
Ted Kremenek03325582013-02-21 01:29:01 +0000652 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000653 if (!V.hasValue())
654 continue;
655 if (!V.getValue())
656 return false;
657 if (Visit(Cursor, true))
658 return true;
659 }
660 return false;
661}
662
663bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
664 llvm_unreachable("Translation units are visited directly by Visit()");
665}
666
Sergey Kalinichev8f3b1872015-11-15 13:48:32 +0000667bool CursorVisitor::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {
668 if (VisitTemplateParameters(D->getTemplateParameters()))
669 return true;
670
671 return Visit(MakeCXCursor(D->getTemplatedDecl(), TU, RegionOfInterest));
672}
673
Guy Benyei11169dd2012-12-18 14:30:41 +0000674bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
675 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
676 return Visit(TSInfo->getTypeLoc());
677
678 return false;
679}
680
681bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
682 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
683 return Visit(TSInfo->getTypeLoc());
684
685 return false;
686}
687
688bool CursorVisitor::VisitTagDecl(TagDecl *D) {
689 return VisitDeclContext(D);
690}
691
692bool CursorVisitor::VisitClassTemplateSpecializationDecl(
693 ClassTemplateSpecializationDecl *D) {
694 bool ShouldVisitBody = false;
695 switch (D->getSpecializationKind()) {
696 case TSK_Undeclared:
697 case TSK_ImplicitInstantiation:
698 // Nothing to visit
699 return false;
700
701 case TSK_ExplicitInstantiationDeclaration:
702 case TSK_ExplicitInstantiationDefinition:
703 break;
704
705 case TSK_ExplicitSpecialization:
706 ShouldVisitBody = true;
707 break;
708 }
709
710 // Visit the template arguments used in the specialization.
711 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
712 TypeLoc TL = SpecType->getTypeLoc();
David Blaikie6adc78e2013-02-18 22:06:02 +0000713 if (TemplateSpecializationTypeLoc TSTLoc =
714 TL.getAs<TemplateSpecializationTypeLoc>()) {
715 for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
716 if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000717 return true;
718 }
719 }
Alexander Kornienko1a9f1842015-12-28 15:24:08 +0000720
721 return ShouldVisitBody && VisitCXXRecordDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +0000722}
723
724bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
725 ClassTemplatePartialSpecializationDecl *D) {
726 // FIXME: Visit the "outer" template parameter lists on the TagDecl
727 // before visiting these template parameters.
728 if (VisitTemplateParameters(D->getTemplateParameters()))
729 return true;
730
731 // Visit the partial specialization arguments.
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000732 const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
733 const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
734 for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
Guy Benyei11169dd2012-12-18 14:30:41 +0000735 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
736 return true;
737
738 return VisitCXXRecordDecl(D);
739}
740
741bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
742 // Visit the default argument.
743 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
744 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
745 if (Visit(DefArg->getTypeLoc()))
746 return true;
747
748 return false;
749}
750
751bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
752 if (Expr *Init = D->getInitExpr())
753 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
754 return false;
755}
756
757bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000758 unsigned NumParamList = DD->getNumTemplateParameterLists();
759 for (unsigned i = 0; i < NumParamList; i++) {
760 TemplateParameterList* Params = DD->getTemplateParameterList(i);
761 if (VisitTemplateParameters(Params))
762 return true;
763 }
764
Guy Benyei11169dd2012-12-18 14:30:41 +0000765 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
766 if (Visit(TSInfo->getTypeLoc()))
767 return true;
768
769 // Visit the nested-name-specifier, if present.
770 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
771 if (VisitNestedNameSpecifierLoc(QualifierLoc))
772 return true;
773
774 return false;
775}
776
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000777/// \brief Compare two base or member initializers based on their source order.
778static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
779 CXXCtorInitializer *const *Y) {
780 return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
781}
782
Guy Benyei11169dd2012-12-18 14:30:41 +0000783bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000784 unsigned NumParamList = ND->getNumTemplateParameterLists();
785 for (unsigned i = 0; i < NumParamList; i++) {
786 TemplateParameterList* Params = ND->getTemplateParameterList(i);
787 if (VisitTemplateParameters(Params))
788 return true;
789 }
790
Guy Benyei11169dd2012-12-18 14:30:41 +0000791 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
792 // Visit the function declaration's syntactic components in the order
793 // written. This requires a bit of work.
794 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
David Blaikie6adc78e2013-02-18 22:06:02 +0000795 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Guy Benyei11169dd2012-12-18 14:30:41 +0000796
797 // If we have a function declared directly (without the use of a typedef),
798 // visit just the return type. Otherwise, just visit the function's type
799 // now.
Alp Toker42a16a62014-01-25 23:51:36 +0000800 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getReturnLoc())) ||
Guy Benyei11169dd2012-12-18 14:30:41 +0000801 (!FTL && Visit(TL)))
802 return true;
803
804 // Visit the nested-name-specifier, if present.
805 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
806 if (VisitNestedNameSpecifierLoc(QualifierLoc))
807 return true;
808
809 // Visit the declaration name.
Argyrios Kyrtzidis4a4d2b42014-02-09 08:13:47 +0000810 if (!isa<CXXDestructorDecl>(ND))
811 if (VisitDeclarationNameInfo(ND->getNameInfo()))
812 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +0000813
814 // FIXME: Visit explicitly-specified template arguments!
815
816 // Visit the function parameters, if we have a function type.
David Blaikie6adc78e2013-02-18 22:06:02 +0000817 if (FTL && VisitFunctionTypeLoc(FTL, true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000818 return true;
819
Bill Wendling44426052012-12-20 19:22:21 +0000820 // FIXME: Attributes?
Guy Benyei11169dd2012-12-18 14:30:41 +0000821 }
822
823 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
824 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
825 // Find the initializers that were written in the source.
826 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
Aaron Ballman0ad78302014-03-13 17:34:31 +0000827 for (auto *I : Constructor->inits()) {
828 if (!I->isWritten())
Guy Benyei11169dd2012-12-18 14:30:41 +0000829 continue;
830
Aaron Ballman0ad78302014-03-13 17:34:31 +0000831 WrittenInits.push_back(I);
Guy Benyei11169dd2012-12-18 14:30:41 +0000832 }
833
834 // Sort the initializers in source order
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000835 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
836 &CompareCXXCtorInitializers);
837
Guy Benyei11169dd2012-12-18 14:30:41 +0000838 // Visit the initializers in source order
839 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
840 CXXCtorInitializer *Init = WrittenInits[I];
841 if (Init->isAnyMemberInitializer()) {
842 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
843 Init->getMemberLocation(), TU)))
844 return true;
845 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
846 if (Visit(TInfo->getTypeLoc()))
847 return true;
848 }
849
850 // Visit the initializer value.
851 if (Expr *Initializer = Init->getInit())
852 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
853 return true;
854 }
855 }
856
857 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
858 return true;
859 }
860
861 return false;
862}
863
864bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
865 if (VisitDeclaratorDecl(D))
866 return true;
867
868 if (Expr *BitWidth = D->getBitWidth())
869 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
870
871 return false;
872}
873
874bool CursorVisitor::VisitVarDecl(VarDecl *D) {
875 if (VisitDeclaratorDecl(D))
876 return true;
877
878 if (Expr *Init = D->getInit())
879 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
880
881 return false;
882}
883
884bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
885 if (VisitDeclaratorDecl(D))
886 return true;
887
888 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
889 if (Expr *DefArg = D->getDefaultArgument())
890 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
891
892 return false;
893}
894
895bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
896 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
897 // before visiting these template parameters.
898 if (VisitTemplateParameters(D->getTemplateParameters()))
899 return true;
900
901 return VisitFunctionDecl(D->getTemplatedDecl());
902}
903
904bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
905 // FIXME: Visit the "outer" template parameter lists on the TagDecl
906 // before visiting these template parameters.
907 if (VisitTemplateParameters(D->getTemplateParameters()))
908 return true;
909
910 return VisitCXXRecordDecl(D->getTemplatedDecl());
911}
912
913bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
914 if (VisitTemplateParameters(D->getTemplateParameters()))
915 return true;
916
917 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
918 VisitTemplateArgumentLoc(D->getDefaultArgument()))
919 return true;
920
921 return false;
922}
923
Douglas Gregor9bda6cf2015-07-07 03:58:14 +0000924bool CursorVisitor::VisitObjCTypeParamDecl(ObjCTypeParamDecl *D) {
925 // Visit the bound, if it's explicit.
926 if (D->hasExplicitBound()) {
927 if (auto TInfo = D->getTypeSourceInfo()) {
928 if (Visit(TInfo->getTypeLoc()))
929 return true;
930 }
931 }
932
933 return false;
934}
935
Guy Benyei11169dd2012-12-18 14:30:41 +0000936bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Alp Toker314cc812014-01-25 16:55:45 +0000937 if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
Guy Benyei11169dd2012-12-18 14:30:41 +0000938 if (Visit(TSInfo->getTypeLoc()))
939 return true;
940
Aaron Ballman43b68be2014-03-07 17:50:17 +0000941 for (const auto *P : ND->params()) {
942 if (Visit(MakeCXCursor(P, TU, RegionOfInterest)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000943 return true;
944 }
945
Alexander Kornienko1a9f1842015-12-28 15:24:08 +0000946 return ND->isThisDeclarationADefinition() &&
947 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest));
Guy Benyei11169dd2012-12-18 14:30:41 +0000948}
949
950template <typename DeclIt>
951static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
952 SourceManager &SM, SourceLocation EndLoc,
953 SmallVectorImpl<Decl *> &Decls) {
954 DeclIt next = *DI_current;
955 while (++next != DE_current) {
956 Decl *D_next = *next;
957 if (!D_next)
958 break;
959 SourceLocation L = D_next->getLocStart();
960 if (!L.isValid())
961 break;
962 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
963 *DI_current = next;
964 Decls.push_back(D_next);
965 continue;
966 }
967 break;
968 }
969}
970
Guy Benyei11169dd2012-12-18 14:30:41 +0000971bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
972 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
973 // an @implementation can lexically contain Decls that are not properly
974 // nested in the AST. When we identify such cases, we need to retrofit
975 // this nesting here.
976 if (!DI_current && !FileDI_current)
977 return VisitDeclContext(D);
978
979 // Scan the Decls that immediately come after the container
980 // in the current DeclContext. If any fall within the
981 // container's lexical region, stash them into a vector
982 // for later processing.
983 SmallVector<Decl *, 24> DeclsInContainer;
984 SourceLocation EndLoc = D->getSourceRange().getEnd();
985 SourceManager &SM = AU->getSourceManager();
986 if (EndLoc.isValid()) {
987 if (DI_current) {
988 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
989 DeclsInContainer);
990 } else {
991 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
992 DeclsInContainer);
993 }
994 }
995
996 // The common case.
997 if (DeclsInContainer.empty())
998 return VisitDeclContext(D);
999
1000 // Get all the Decls in the DeclContext, and sort them with the
1001 // additional ones we've collected. Then visit them.
Aaron Ballman629afae2014-03-07 19:56:05 +00001002 for (auto *SubDecl : D->decls()) {
1003 if (!SubDecl || SubDecl->getLexicalDeclContext() != D ||
1004 SubDecl->getLocStart().isInvalid())
Guy Benyei11169dd2012-12-18 14:30:41 +00001005 continue;
Aaron Ballman629afae2014-03-07 19:56:05 +00001006 DeclsInContainer.push_back(SubDecl);
Guy Benyei11169dd2012-12-18 14:30:41 +00001007 }
1008
1009 // Now sort the Decls so that they appear in lexical order.
1010 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
Benjamin Kramerbbdd7642014-03-01 14:48:57 +00001011 [&SM](Decl *A, Decl *B) {
1012 SourceLocation L_A = A->getLocStart();
1013 SourceLocation L_B = B->getLocStart();
1014 assert(L_A.isValid() && L_B.isValid());
1015 return SM.isBeforeInTranslationUnit(L_A, L_B);
1016 });
Guy Benyei11169dd2012-12-18 14:30:41 +00001017
1018 // Now visit the decls.
1019 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
1020 E = DeclsInContainer.end(); I != E; ++I) {
1021 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek03325582013-02-21 01:29:01 +00001022 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00001023 if (!V.hasValue())
1024 continue;
1025 if (!V.getValue())
1026 return false;
1027 if (Visit(Cursor, true))
1028 return true;
1029 }
1030 return false;
1031}
1032
1033bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1034 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1035 TU)))
1036 return true;
1037
Douglas Gregore9d95f12015-07-07 03:57:35 +00001038 if (VisitObjCTypeParamList(ND->getTypeParamList()))
1039 return true;
1040
Guy Benyei11169dd2012-12-18 14:30:41 +00001041 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1042 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1043 E = ND->protocol_end(); I != E; ++I, ++PL)
1044 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1045 return true;
1046
1047 return VisitObjCContainerDecl(ND);
1048}
1049
1050bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1051 if (!PID->isThisDeclarationADefinition())
1052 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1053
1054 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1055 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1056 E = PID->protocol_end(); I != E; ++I, ++PL)
1057 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1058 return true;
1059
1060 return VisitObjCContainerDecl(PID);
1061}
1062
1063bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1064 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1065 return true;
1066
1067 // FIXME: This implements a workaround with @property declarations also being
1068 // installed in the DeclContext for the @interface. Eventually this code
1069 // should be removed.
1070 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1071 if (!CDecl || !CDecl->IsClassExtension())
1072 return false;
1073
1074 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1075 if (!ID)
1076 return false;
1077
1078 IdentifierInfo *PropertyId = PD->getIdentifier();
1079 ObjCPropertyDecl *prevDecl =
1080 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1081
1082 if (!prevDecl)
1083 return false;
1084
1085 // Visit synthesized methods since they will be skipped when visiting
1086 // the @interface.
1087 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1088 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1089 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1090 return true;
1091
1092 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1093 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1094 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1095 return true;
1096
1097 return false;
1098}
1099
Douglas Gregore9d95f12015-07-07 03:57:35 +00001100bool CursorVisitor::VisitObjCTypeParamList(ObjCTypeParamList *typeParamList) {
1101 if (!typeParamList)
1102 return false;
1103
1104 for (auto *typeParam : *typeParamList) {
1105 // Visit the type parameter.
1106 if (Visit(MakeCXCursor(typeParam, TU, RegionOfInterest)))
1107 return true;
Douglas Gregore9d95f12015-07-07 03:57:35 +00001108 }
1109
1110 return false;
1111}
1112
Guy Benyei11169dd2012-12-18 14:30:41 +00001113bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1114 if (!D->isThisDeclarationADefinition()) {
1115 // Forward declaration is treated like a reference.
1116 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1117 }
1118
Douglas Gregore9d95f12015-07-07 03:57:35 +00001119 // Objective-C type parameters.
1120 if (VisitObjCTypeParamList(D->getTypeParamListAsWritten()))
1121 return true;
1122
Guy Benyei11169dd2012-12-18 14:30:41 +00001123 // Issue callbacks for super class.
1124 if (D->getSuperClass() &&
1125 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1126 D->getSuperClassLoc(),
1127 TU)))
1128 return true;
1129
Douglas Gregore9d95f12015-07-07 03:57:35 +00001130 if (TypeSourceInfo *SuperClassTInfo = D->getSuperClassTInfo())
1131 if (Visit(SuperClassTInfo->getTypeLoc()))
1132 return true;
1133
Guy Benyei11169dd2012-12-18 14:30:41 +00001134 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1135 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1136 E = D->protocol_end(); I != E; ++I, ++PL)
1137 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1138 return true;
1139
1140 return VisitObjCContainerDecl(D);
1141}
1142
1143bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1144 return VisitObjCContainerDecl(D);
1145}
1146
1147bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1148 // 'ID' could be null when dealing with invalid code.
1149 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1150 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1151 return true;
1152
1153 return VisitObjCImplDecl(D);
1154}
1155
1156bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1157#if 0
1158 // Issue callbacks for super class.
1159 // FIXME: No source location information!
1160 if (D->getSuperClass() &&
1161 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1162 D->getSuperClassLoc(),
1163 TU)))
1164 return true;
1165#endif
1166
1167 return VisitObjCImplDecl(D);
1168}
1169
1170bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1171 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1172 if (PD->isIvarNameSpecified())
1173 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1174
1175 return false;
1176}
1177
1178bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1179 return VisitDeclContext(D);
1180}
1181
1182bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1183 // Visit nested-name-specifier.
1184 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1185 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1186 return true;
1187
1188 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1189 D->getTargetNameLoc(), TU));
1190}
1191
1192bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1193 // Visit nested-name-specifier.
1194 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1195 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1196 return true;
1197 }
1198
1199 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1200 return true;
1201
1202 return VisitDeclarationNameInfo(D->getNameInfo());
1203}
1204
1205bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1206 // Visit nested-name-specifier.
1207 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1208 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1209 return true;
1210
1211 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1212 D->getIdentLocation(), TU));
1213}
1214
1215bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1216 // Visit nested-name-specifier.
1217 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1218 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1219 return true;
1220 }
1221
1222 return VisitDeclarationNameInfo(D->getNameInfo());
1223}
1224
1225bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1226 UnresolvedUsingTypenameDecl *D) {
1227 // Visit nested-name-specifier.
1228 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1229 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1230 return true;
1231
1232 return false;
1233}
1234
1235bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1236 switch (Name.getName().getNameKind()) {
1237 case clang::DeclarationName::Identifier:
1238 case clang::DeclarationName::CXXLiteralOperatorName:
1239 case clang::DeclarationName::CXXOperatorName:
1240 case clang::DeclarationName::CXXUsingDirective:
1241 return false;
1242
1243 case clang::DeclarationName::CXXConstructorName:
1244 case clang::DeclarationName::CXXDestructorName:
1245 case clang::DeclarationName::CXXConversionFunctionName:
1246 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1247 return Visit(TSInfo->getTypeLoc());
1248 return false;
1249
1250 case clang::DeclarationName::ObjCZeroArgSelector:
1251 case clang::DeclarationName::ObjCOneArgSelector:
1252 case clang::DeclarationName::ObjCMultiArgSelector:
1253 // FIXME: Per-identifier location info?
1254 return false;
1255 }
1256
1257 llvm_unreachable("Invalid DeclarationName::Kind!");
1258}
1259
1260bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1261 SourceRange Range) {
1262 // FIXME: This whole routine is a hack to work around the lack of proper
1263 // source information in nested-name-specifiers (PR5791). Since we do have
1264 // a beginning source location, we can visit the first component of the
1265 // nested-name-specifier, if it's a single-token component.
1266 if (!NNS)
1267 return false;
1268
1269 // Get the first component in the nested-name-specifier.
1270 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1271 NNS = Prefix;
1272
1273 switch (NNS->getKind()) {
1274 case NestedNameSpecifier::Namespace:
1275 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1276 TU));
1277
1278 case NestedNameSpecifier::NamespaceAlias:
1279 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1280 Range.getBegin(), TU));
1281
1282 case NestedNameSpecifier::TypeSpec: {
1283 // If the type has a form where we know that the beginning of the source
1284 // range matches up with a reference cursor. Visit the appropriate reference
1285 // cursor.
1286 const Type *T = NNS->getAsType();
1287 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1288 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1289 if (const TagType *Tag = dyn_cast<TagType>(T))
1290 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1291 if (const TemplateSpecializationType *TST
1292 = dyn_cast<TemplateSpecializationType>(T))
1293 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1294 break;
1295 }
1296
1297 case NestedNameSpecifier::TypeSpecWithTemplate:
1298 case NestedNameSpecifier::Global:
1299 case NestedNameSpecifier::Identifier:
Nikola Smiljanic67860242014-09-26 00:28:20 +00001300 case NestedNameSpecifier::Super:
Guy Benyei11169dd2012-12-18 14:30:41 +00001301 break;
1302 }
1303
1304 return false;
1305}
1306
1307bool
1308CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1309 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1310 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1311 Qualifiers.push_back(Qualifier);
1312
1313 while (!Qualifiers.empty()) {
1314 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1315 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1316 switch (NNS->getKind()) {
1317 case NestedNameSpecifier::Namespace:
1318 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1319 Q.getLocalBeginLoc(),
1320 TU)))
1321 return true;
1322
1323 break;
1324
1325 case NestedNameSpecifier::NamespaceAlias:
1326 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1327 Q.getLocalBeginLoc(),
1328 TU)))
1329 return true;
1330
1331 break;
1332
1333 case NestedNameSpecifier::TypeSpec:
1334 case NestedNameSpecifier::TypeSpecWithTemplate:
1335 if (Visit(Q.getTypeLoc()))
1336 return true;
1337
1338 break;
1339
1340 case NestedNameSpecifier::Global:
1341 case NestedNameSpecifier::Identifier:
Nikola Smiljanic67860242014-09-26 00:28:20 +00001342 case NestedNameSpecifier::Super:
Guy Benyei11169dd2012-12-18 14:30:41 +00001343 break;
1344 }
1345 }
1346
1347 return false;
1348}
1349
1350bool CursorVisitor::VisitTemplateParameters(
1351 const TemplateParameterList *Params) {
1352 if (!Params)
1353 return false;
1354
1355 for (TemplateParameterList::const_iterator P = Params->begin(),
1356 PEnd = Params->end();
1357 P != PEnd; ++P) {
1358 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1359 return true;
1360 }
1361
1362 return false;
1363}
1364
1365bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1366 switch (Name.getKind()) {
1367 case TemplateName::Template:
1368 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1369
1370 case TemplateName::OverloadedTemplate:
1371 // Visit the overloaded template set.
1372 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1373 return true;
1374
1375 return false;
1376
1377 case TemplateName::DependentTemplate:
1378 // FIXME: Visit nested-name-specifier.
1379 return false;
1380
1381 case TemplateName::QualifiedTemplate:
1382 // FIXME: Visit nested-name-specifier.
1383 return Visit(MakeCursorTemplateRef(
1384 Name.getAsQualifiedTemplateName()->getDecl(),
1385 Loc, TU));
1386
1387 case TemplateName::SubstTemplateTemplateParm:
1388 return Visit(MakeCursorTemplateRef(
1389 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1390 Loc, TU));
1391
1392 case TemplateName::SubstTemplateTemplateParmPack:
1393 return Visit(MakeCursorTemplateRef(
1394 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1395 Loc, TU));
1396 }
1397
1398 llvm_unreachable("Invalid TemplateName::Kind!");
1399}
1400
1401bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1402 switch (TAL.getArgument().getKind()) {
1403 case TemplateArgument::Null:
1404 case TemplateArgument::Integral:
1405 case TemplateArgument::Pack:
1406 return false;
1407
1408 case TemplateArgument::Type:
1409 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1410 return Visit(TSInfo->getTypeLoc());
1411 return false;
1412
1413 case TemplateArgument::Declaration:
1414 if (Expr *E = TAL.getSourceDeclExpression())
1415 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1416 return false;
1417
1418 case TemplateArgument::NullPtr:
1419 if (Expr *E = TAL.getSourceNullPtrExpression())
1420 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1421 return false;
1422
1423 case TemplateArgument::Expression:
1424 if (Expr *E = TAL.getSourceExpression())
1425 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1426 return false;
1427
1428 case TemplateArgument::Template:
1429 case TemplateArgument::TemplateExpansion:
1430 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1431 return true;
1432
1433 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1434 TAL.getTemplateNameLoc());
1435 }
1436
1437 llvm_unreachable("Invalid TemplateArgument::Kind!");
1438}
1439
1440bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1441 return VisitDeclContext(D);
1442}
1443
1444bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1445 return Visit(TL.getUnqualifiedLoc());
1446}
1447
1448bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1449 ASTContext &Context = AU->getASTContext();
1450
1451 // Some builtin types (such as Objective-C's "id", "sel", and
1452 // "Class") have associated declarations. Create cursors for those.
1453 QualType VisitType;
1454 switch (TL.getTypePtr()->getKind()) {
1455
1456 case BuiltinType::Void:
1457 case BuiltinType::NullPtr:
1458 case BuiltinType::Dependent:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001459 case BuiltinType::OCLImage1d:
1460 case BuiltinType::OCLImage1dArray:
1461 case BuiltinType::OCLImage1dBuffer:
1462 case BuiltinType::OCLImage2d:
1463 case BuiltinType::OCLImage2dArray:
Alexey Bader9c8453f2015-09-15 11:18:52 +00001464 case BuiltinType::OCLImage2dDepth:
1465 case BuiltinType::OCLImage2dArrayDepth:
1466 case BuiltinType::OCLImage2dMSAA:
1467 case BuiltinType::OCLImage2dArrayMSAA:
1468 case BuiltinType::OCLImage2dMSAADepth:
1469 case BuiltinType::OCLImage2dArrayMSAADepth:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001470 case BuiltinType::OCLImage3d:
NAKAMURA Takumi288c42e2013-02-07 12:47:42 +00001471 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +00001472 case BuiltinType::OCLEvent:
Alexey Bader9c8453f2015-09-15 11:18:52 +00001473 case BuiltinType::OCLClkEvent:
1474 case BuiltinType::OCLQueue:
1475 case BuiltinType::OCLNDRange:
1476 case BuiltinType::OCLReserveID:
Guy Benyei11169dd2012-12-18 14:30:41 +00001477#define BUILTIN_TYPE(Id, SingletonId)
1478#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1479#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1480#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1481#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1482#include "clang/AST/BuiltinTypes.def"
1483 break;
1484
1485 case BuiltinType::ObjCId:
1486 VisitType = Context.getObjCIdType();
1487 break;
1488
1489 case BuiltinType::ObjCClass:
1490 VisitType = Context.getObjCClassType();
1491 break;
1492
1493 case BuiltinType::ObjCSel:
1494 VisitType = Context.getObjCSelType();
1495 break;
1496 }
1497
1498 if (!VisitType.isNull()) {
1499 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1500 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1501 TU));
1502 }
1503
1504 return false;
1505}
1506
1507bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1508 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1509}
1510
1511bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1512 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1513}
1514
1515bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1516 if (TL.isDefinition())
1517 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1518
1519 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1520}
1521
1522bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1523 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1524}
1525
1526bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
Hans Wennborg59dbe862015-09-29 20:56:43 +00001527 return Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +00001528}
1529
1530bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1531 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1532 return true;
1533
Douglas Gregore9d95f12015-07-07 03:57:35 +00001534 for (unsigned I = 0, N = TL.getNumTypeArgs(); I != N; ++I) {
1535 if (Visit(TL.getTypeArgTInfo(I)->getTypeLoc()))
1536 return true;
1537 }
1538
Guy Benyei11169dd2012-12-18 14:30:41 +00001539 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1540 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1541 TU)))
1542 return true;
1543 }
1544
1545 return false;
1546}
1547
1548bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1549 return Visit(TL.getPointeeLoc());
1550}
1551
1552bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1553 return Visit(TL.getInnerLoc());
1554}
1555
1556bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1557 return Visit(TL.getPointeeLoc());
1558}
1559
1560bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1561 return Visit(TL.getPointeeLoc());
1562}
1563
1564bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1565 return Visit(TL.getPointeeLoc());
1566}
1567
1568bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1569 return Visit(TL.getPointeeLoc());
1570}
1571
1572bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1573 return Visit(TL.getPointeeLoc());
1574}
1575
1576bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1577 return Visit(TL.getModifiedLoc());
1578}
1579
1580bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1581 bool SkipResultType) {
Alp Toker42a16a62014-01-25 23:51:36 +00001582 if (!SkipResultType && Visit(TL.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001583 return true;
1584
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00001585 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1586 if (Decl *D = TL.getParam(I))
Guy Benyei11169dd2012-12-18 14:30:41 +00001587 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1588 return true;
1589
1590 return false;
1591}
1592
1593bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1594 if (Visit(TL.getElementLoc()))
1595 return true;
1596
1597 if (Expr *Size = TL.getSizeExpr())
1598 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1599
1600 return false;
1601}
1602
Reid Kleckner8a365022013-06-24 17:51:48 +00001603bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1604 return Visit(TL.getOriginalLoc());
1605}
1606
Reid Kleckner0503a872013-12-05 01:23:43 +00001607bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1608 return Visit(TL.getOriginalLoc());
1609}
1610
Guy Benyei11169dd2012-12-18 14:30:41 +00001611bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1612 TemplateSpecializationTypeLoc TL) {
1613 // Visit the template name.
1614 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1615 TL.getTemplateNameLoc()))
1616 return true;
1617
1618 // Visit the template arguments.
1619 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1620 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1621 return true;
1622
1623 return false;
1624}
1625
1626bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1627 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1628}
1629
1630bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1631 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1632 return Visit(TSInfo->getTypeLoc());
1633
1634 return false;
1635}
1636
1637bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1638 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1639 return Visit(TSInfo->getTypeLoc());
1640
1641 return false;
1642}
1643
1644bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
Hans Wennborg59dbe862015-09-29 20:56:43 +00001645 return VisitNestedNameSpecifierLoc(TL.getQualifierLoc());
Guy Benyei11169dd2012-12-18 14:30:41 +00001646}
1647
1648bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1649 DependentTemplateSpecializationTypeLoc TL) {
1650 // Visit the nested-name-specifier, if there is one.
1651 if (TL.getQualifierLoc() &&
1652 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1653 return true;
1654
1655 // Visit the template arguments.
1656 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1657 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1658 return true;
1659
1660 return false;
1661}
1662
1663bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1664 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1665 return true;
1666
1667 return Visit(TL.getNamedTypeLoc());
1668}
1669
1670bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1671 return Visit(TL.getPatternLoc());
1672}
1673
1674bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1675 if (Expr *E = TL.getUnderlyingExpr())
1676 return Visit(MakeCXCursor(E, StmtParent, TU));
1677
1678 return false;
1679}
1680
1681bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1682 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1683}
1684
1685bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1686 return Visit(TL.getValueLoc());
1687}
1688
Xiuli Pan9c14e282016-01-09 12:53:17 +00001689bool CursorVisitor::VisitPipeTypeLoc(PipeTypeLoc TL) {
1690 return Visit(TL.getValueLoc());
1691}
1692
Guy Benyei11169dd2012-12-18 14:30:41 +00001693#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1694bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1695 return Visit##PARENT##Loc(TL); \
1696}
1697
1698DEFAULT_TYPELOC_IMPL(Complex, Type)
1699DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1700DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1701DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1702DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1703DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1704DEFAULT_TYPELOC_IMPL(Vector, Type)
1705DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1706DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1707DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1708DEFAULT_TYPELOC_IMPL(Record, TagType)
1709DEFAULT_TYPELOC_IMPL(Enum, TagType)
1710DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1711DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1712DEFAULT_TYPELOC_IMPL(Auto, Type)
1713
1714bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1715 // Visit the nested-name-specifier, if present.
1716 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1717 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1718 return true;
1719
1720 if (D->isCompleteDefinition()) {
Aaron Ballman574705e2014-03-13 15:41:46 +00001721 for (const auto &I : D->bases()) {
1722 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001723 return true;
1724 }
1725 }
1726
1727 return VisitTagDecl(D);
1728}
1729
1730bool CursorVisitor::VisitAttributes(Decl *D) {
Aaron Ballmanb97112e2014-03-08 22:19:01 +00001731 for (const auto *I : D->attrs())
1732 if (Visit(MakeCXCursor(I, D, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001733 return true;
1734
1735 return false;
1736}
1737
1738//===----------------------------------------------------------------------===//
1739// Data-recursive visitor methods.
1740//===----------------------------------------------------------------------===//
1741
1742namespace {
1743#define DEF_JOB(NAME, DATA, KIND)\
1744class NAME : public VisitorJob {\
1745public:\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001746 NAME(const DATA *d, CXCursor parent) : \
1747 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei11169dd2012-12-18 14:30:41 +00001748 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001749 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei11169dd2012-12-18 14:30:41 +00001750};
1751
1752DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1753DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1754DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1755DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
Guy Benyei11169dd2012-12-18 14:30:41 +00001756DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1757DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1758DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1759#undef DEF_JOB
1760
James Y Knight04ec5bf2015-12-24 02:59:37 +00001761class ExplicitTemplateArgsVisit : public VisitorJob {
1762public:
1763 ExplicitTemplateArgsVisit(const TemplateArgumentLoc *Begin,
1764 const TemplateArgumentLoc *End, CXCursor parent)
1765 : VisitorJob(parent, VisitorJob::ExplicitTemplateArgsVisitKind, Begin,
1766 End) {}
1767 static bool classof(const VisitorJob *VJ) {
1768 return VJ->getKind() == ExplicitTemplateArgsVisitKind;
1769 }
1770 const TemplateArgumentLoc *begin() const {
1771 return static_cast<const TemplateArgumentLoc *>(data[0]);
1772 }
1773 const TemplateArgumentLoc *end() {
1774 return static_cast<const TemplateArgumentLoc *>(data[1]);
1775 }
1776};
Guy Benyei11169dd2012-12-18 14:30:41 +00001777class DeclVisit : public VisitorJob {
1778public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001779 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei11169dd2012-12-18 14:30:41 +00001780 VisitorJob(parent, VisitorJob::DeclVisitKind,
Craig Topper69186e72014-06-08 08:38:04 +00001781 D, isFirst ? (void*) 1 : (void*) nullptr) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001782 static bool classof(const VisitorJob *VJ) {
1783 return VJ->getKind() == DeclVisitKind;
1784 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001785 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Dmitri Gribenkoe5423a72015-03-23 19:23:50 +00001786 bool isFirst() const { return data[1] != nullptr; }
Guy Benyei11169dd2012-12-18 14:30:41 +00001787};
1788class TypeLocVisit : public VisitorJob {
1789public:
1790 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1791 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1792 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1793
1794 static bool classof(const VisitorJob *VJ) {
1795 return VJ->getKind() == TypeLocVisitKind;
1796 }
1797
1798 TypeLoc get() const {
1799 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001800 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001801 }
1802};
1803
1804class LabelRefVisit : public VisitorJob {
1805public:
1806 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1807 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1808 labelLoc.getPtrEncoding()) {}
1809
1810 static bool classof(const VisitorJob *VJ) {
1811 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1812 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001813 const LabelDecl *get() const {
1814 return static_cast<const LabelDecl *>(data[0]);
1815 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001816 SourceLocation getLoc() const {
1817 return SourceLocation::getFromPtrEncoding(data[1]); }
1818};
1819
1820class NestedNameSpecifierLocVisit : public VisitorJob {
1821public:
1822 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1823 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1824 Qualifier.getNestedNameSpecifier(),
1825 Qualifier.getOpaqueData()) { }
1826
1827 static bool classof(const VisitorJob *VJ) {
1828 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1829 }
1830
1831 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001832 return NestedNameSpecifierLoc(
1833 const_cast<NestedNameSpecifier *>(
1834 static_cast<const NestedNameSpecifier *>(data[0])),
1835 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001836 }
1837};
1838
1839class DeclarationNameInfoVisit : public VisitorJob {
1840public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001841 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001842 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001843 static bool classof(const VisitorJob *VJ) {
1844 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1845 }
1846 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001847 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001848 switch (S->getStmtClass()) {
1849 default:
1850 llvm_unreachable("Unhandled Stmt");
1851 case clang::Stmt::MSDependentExistsStmtClass:
1852 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1853 case Stmt::CXXDependentScopeMemberExprClass:
1854 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1855 case Stmt::DependentScopeDeclRefExprClass:
1856 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001857 case Stmt::OMPCriticalDirectiveClass:
1858 return cast<OMPCriticalDirective>(S)->getDirectiveName();
Guy Benyei11169dd2012-12-18 14:30:41 +00001859 }
1860 }
1861};
1862class MemberRefVisit : public VisitorJob {
1863public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001864 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei11169dd2012-12-18 14:30:41 +00001865 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1866 L.getPtrEncoding()) {}
1867 static bool classof(const VisitorJob *VJ) {
1868 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1869 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001870 const FieldDecl *get() const {
1871 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001872 }
1873 SourceLocation getLoc() const {
1874 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1875 }
1876};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001877class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001878 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001879 VisitorWorkList &WL;
1880 CXCursor Parent;
1881public:
1882 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1883 : WL(wl), Parent(parent) {}
1884
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001885 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1886 void VisitBlockExpr(const BlockExpr *B);
1887 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1888 void VisitCompoundStmt(const CompoundStmt *S);
1889 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1890 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1891 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1892 void VisitCXXNewExpr(const CXXNewExpr *E);
1893 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1894 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1895 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1896 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1897 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1898 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1899 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1900 void VisitCXXCatchStmt(const CXXCatchStmt *S);
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00001901 void VisitCXXForRangeStmt(const CXXForRangeStmt *S);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001902 void VisitDeclRefExpr(const DeclRefExpr *D);
1903 void VisitDeclStmt(const DeclStmt *S);
1904 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1905 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1906 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1907 void VisitForStmt(const ForStmt *FS);
1908 void VisitGotoStmt(const GotoStmt *GS);
1909 void VisitIfStmt(const IfStmt *If);
1910 void VisitInitListExpr(const InitListExpr *IE);
1911 void VisitMemberExpr(const MemberExpr *M);
1912 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1913 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1914 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1915 void VisitOverloadExpr(const OverloadExpr *E);
1916 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1917 void VisitStmt(const Stmt *S);
1918 void VisitSwitchStmt(const SwitchStmt *S);
1919 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001920 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1921 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1922 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1923 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1924 void VisitVAArgExpr(const VAArgExpr *E);
1925 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1926 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1927 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1928 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001929 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
Alexander Musman3aaab662014-08-19 11:27:13 +00001930 void VisitOMPLoopDirective(const OMPLoopDirective *D);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001931 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00001932 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00001933 void VisitOMPForDirective(const OMPForDirective *D);
Alexander Musmanf82886e2014-09-18 05:12:34 +00001934 void VisitOMPForSimdDirective(const OMPForSimdDirective *D);
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00001935 void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
Alexey Bataev1e0498a2014-06-26 08:21:58 +00001936 void VisitOMPSectionDirective(const OMPSectionDirective *D);
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00001937 void VisitOMPSingleDirective(const OMPSingleDirective *D);
Alexander Musman80c22892014-07-17 08:54:58 +00001938 void VisitOMPMasterDirective(const OMPMasterDirective *D);
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001939 void VisitOMPCriticalDirective(const OMPCriticalDirective *D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00001940 void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
Alexander Musmane4e893b2014-09-23 09:33:00 +00001941 void VisitOMPParallelForSimdDirective(const OMPParallelForSimdDirective *D);
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00001942 void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective *D);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00001943 void VisitOMPTaskDirective(const OMPTaskDirective *D);
Alexey Bataev68446b72014-07-18 07:47:19 +00001944 void VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D);
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00001945 void VisitOMPBarrierDirective(const OMPBarrierDirective *D);
Alexey Bataev2df347a2014-07-18 10:17:07 +00001946 void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00001947 void VisitOMPTaskgroupDirective(const OMPTaskgroupDirective *D);
Alexey Bataev6d4ed052015-07-01 06:57:41 +00001948 void
1949 VisitOMPCancellationPointDirective(const OMPCancellationPointDirective *D);
Alexey Bataev80909872015-07-02 11:25:17 +00001950 void VisitOMPCancelDirective(const OMPCancelDirective *D);
Alexey Bataev6125da92014-07-21 11:26:11 +00001951 void VisitOMPFlushDirective(const OMPFlushDirective *D);
Alexey Bataev9fb6e642014-07-22 06:45:04 +00001952 void VisitOMPOrderedDirective(const OMPOrderedDirective *D);
Alexey Bataev0162e452014-07-22 10:10:35 +00001953 void VisitOMPAtomicDirective(const OMPAtomicDirective *D);
Alexey Bataev0bd520b2014-09-19 08:19:49 +00001954 void VisitOMPTargetDirective(const OMPTargetDirective *D);
Michael Wong65f367f2015-07-21 13:44:28 +00001955 void VisitOMPTargetDataDirective(const OMPTargetDataDirective *D);
Samuel Antaodf67fc42016-01-19 19:15:56 +00001956 void VisitOMPTargetEnterDataDirective(const OMPTargetEnterDataDirective *D);
Samuel Antao72590762016-01-19 20:04:50 +00001957 void VisitOMPTargetExitDataDirective(const OMPTargetExitDataDirective *D);
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00001958 void VisitOMPTargetParallelDirective(const OMPTargetParallelDirective *D);
Alexey Bataev13314bf2014-10-09 04:18:56 +00001959 void VisitOMPTeamsDirective(const OMPTeamsDirective *D);
Alexey Bataev49f6e782015-12-01 04:18:41 +00001960 void VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *D);
Alexey Bataev0a6ed842015-12-03 09:40:15 +00001961 void VisitOMPTaskLoopSimdDirective(const OMPTaskLoopSimdDirective *D);
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00001962 void VisitOMPDistributeDirective(const OMPDistributeDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001963
Guy Benyei11169dd2012-12-18 14:30:41 +00001964private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001965 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001966 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
James Y Knight04ec5bf2015-12-24 02:59:37 +00001967 void AddExplicitTemplateArgs(const TemplateArgumentLoc *A,
1968 unsigned NumTemplateArgs);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001969 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1970 void AddStmt(const Stmt *S);
1971 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001972 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001973 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001974 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001975};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00001976} // end anonyous namespace
Guy Benyei11169dd2012-12-18 14:30:41 +00001977
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001978void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001979 // 'S' should always be non-null, since it comes from the
1980 // statement we are visiting.
1981 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1982}
1983
1984void
1985EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1986 if (Qualifier)
1987 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1988}
1989
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001990void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001991 if (S)
1992 WL.push_back(StmtVisit(S, Parent));
1993}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001994void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001995 if (D)
1996 WL.push_back(DeclVisit(D, Parent, isFirst));
1997}
James Y Knight04ec5bf2015-12-24 02:59:37 +00001998void EnqueueVisitor::AddExplicitTemplateArgs(const TemplateArgumentLoc *A,
1999 unsigned NumTemplateArgs) {
2000 WL.push_back(ExplicitTemplateArgsVisit(A, A + NumTemplateArgs, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00002001}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002002void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002003 if (D)
2004 WL.push_back(MemberRefVisit(D, L, Parent));
2005}
2006void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
2007 if (TI)
2008 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
2009 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002010void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002011 unsigned size = WL.size();
Benjamin Kramer642f1732015-07-02 21:03:14 +00002012 for (const Stmt *SubStmt : S->children()) {
2013 AddStmt(SubStmt);
Guy Benyei11169dd2012-12-18 14:30:41 +00002014 }
2015 if (size == WL.size())
2016 return;
2017 // Now reverse the entries we just added. This will match the DFS
2018 // ordering performed by the worklist.
2019 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2020 std::reverse(I, E);
2021}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002022namespace {
2023class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
2024 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00002025 /// \brief Process clauses with list of variables.
2026 template <typename T>
2027 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002028public:
2029 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
2030#define OPENMP_CLAUSE(Name, Class) \
2031 void Visit##Class(const Class *C);
2032#include "clang/Basic/OpenMPKinds.def"
2033};
2034
Alexey Bataevaadd52e2014-02-13 05:29:23 +00002035void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
2036 Visitor->AddStmt(C->getCondition());
2037}
2038
Alexey Bataev3778b602014-07-17 07:32:53 +00002039void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
2040 Visitor->AddStmt(C->getCondition());
2041}
2042
Alexey Bataev568a8332014-03-06 06:15:19 +00002043void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
2044 Visitor->AddStmt(C->getNumThreads());
2045}
2046
Alexey Bataev62c87d22014-03-21 04:51:18 +00002047void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
2048 Visitor->AddStmt(C->getSafelen());
2049}
2050
Alexey Bataev66b15b52015-08-21 11:14:16 +00002051void OMPClauseEnqueue::VisitOMPSimdlenClause(const OMPSimdlenClause *C) {
2052 Visitor->AddStmt(C->getSimdlen());
2053}
2054
Alexander Musman8bd31e62014-05-27 15:12:19 +00002055void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
2056 Visitor->AddStmt(C->getNumForLoops());
2057}
2058
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002059void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00002060
Alexey Bataevbcbadb62014-05-06 06:04:14 +00002061void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
2062
Alexey Bataev56dafe82014-06-20 07:16:17 +00002063void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
2064 Visitor->AddStmt(C->getChunkSize());
Alexey Bataev040d5402015-05-12 08:35:28 +00002065 Visitor->AddStmt(C->getHelperChunkSize());
Alexey Bataev56dafe82014-06-20 07:16:17 +00002066}
2067
Alexey Bataev10e775f2015-07-30 11:36:16 +00002068void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *C) {
2069 Visitor->AddStmt(C->getNumForLoops());
2070}
Alexey Bataev142e1fc2014-06-20 09:44:06 +00002071
Alexey Bataev236070f2014-06-20 11:19:47 +00002072void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
2073
Alexey Bataev7aea99a2014-07-17 12:19:31 +00002074void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
2075
Alexey Bataev74ba3a52014-07-17 12:47:03 +00002076void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
2077
Alexey Bataevf98b00c2014-07-23 02:27:21 +00002078void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}
2079
Alexey Bataevdea47612014-07-23 07:46:59 +00002080void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {}
2081
Alexey Bataev67a4f222014-07-23 10:25:33 +00002082void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {}
2083
Alexey Bataev459dec02014-07-24 06:46:57 +00002084void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}
2085
Alexey Bataev82bad8b2014-07-24 08:55:34 +00002086void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
2087
Alexey Bataev346265e2015-09-25 10:37:12 +00002088void OMPClauseEnqueue::VisitOMPThreadsClause(const OMPThreadsClause *) {}
2089
Alexey Bataevd14d1e62015-09-28 06:39:35 +00002090void OMPClauseEnqueue::VisitOMPSIMDClause(const OMPSIMDClause *) {}
2091
Alexey Bataevb825de12015-12-07 10:51:44 +00002092void OMPClauseEnqueue::VisitOMPNogroupClause(const OMPNogroupClause *) {}
2093
Michael Wonge710d542015-08-07 16:16:36 +00002094void OMPClauseEnqueue::VisitOMPDeviceClause(const OMPDeviceClause *C) {
2095 Visitor->AddStmt(C->getDevice());
2096}
2097
Kelvin Li099bb8c2015-11-24 20:50:12 +00002098void OMPClauseEnqueue::VisitOMPNumTeamsClause(const OMPNumTeamsClause *C) {
2099 Visitor->AddStmt(C->getNumTeams());
2100}
2101
Kelvin Lia15fb1a2015-11-27 18:47:36 +00002102void OMPClauseEnqueue::VisitOMPThreadLimitClause(const OMPThreadLimitClause *C) {
2103 Visitor->AddStmt(C->getThreadLimit());
2104}
2105
Alexey Bataeva0569352015-12-01 10:17:31 +00002106void OMPClauseEnqueue::VisitOMPPriorityClause(const OMPPriorityClause *C) {
2107 Visitor->AddStmt(C->getPriority());
2108}
2109
Alexey Bataev1fd4aed2015-12-07 12:52:51 +00002110void OMPClauseEnqueue::VisitOMPGrainsizeClause(const OMPGrainsizeClause *C) {
2111 Visitor->AddStmt(C->getGrainsize());
2112}
2113
Alexey Bataev382967a2015-12-08 12:06:20 +00002114void OMPClauseEnqueue::VisitOMPNumTasksClause(const OMPNumTasksClause *C) {
2115 Visitor->AddStmt(C->getNumTasks());
2116}
2117
Alexey Bataev28c75412015-12-15 08:19:24 +00002118void OMPClauseEnqueue::VisitOMPHintClause(const OMPHintClause *C) {
2119 Visitor->AddStmt(C->getHint());
2120}
2121
Alexey Bataev756c1962013-09-24 03:17:45 +00002122template<typename T>
2123void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Alexey Bataev03b340a2014-10-21 03:16:40 +00002124 for (const auto *I : Node->varlists()) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00002125 Visitor->AddStmt(I);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002126 }
Alexey Bataev756c1962013-09-24 03:17:45 +00002127}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002128
2129void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002130 VisitOMPClauseList(C);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002131 for (const auto *E : C->private_copies()) {
2132 Visitor->AddStmt(E);
2133 }
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002134}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002135void OMPClauseEnqueue::VisitOMPFirstprivateClause(
2136 const OMPFirstprivateClause *C) {
2137 VisitOMPClauseList(C);
2138}
Alexander Musman1bb328c2014-06-04 13:06:39 +00002139void OMPClauseEnqueue::VisitOMPLastprivateClause(
2140 const OMPLastprivateClause *C) {
2141 VisitOMPClauseList(C);
Alexey Bataev38e89532015-04-16 04:54:05 +00002142 for (auto *E : C->private_copies()) {
2143 Visitor->AddStmt(E);
2144 }
2145 for (auto *E : C->source_exprs()) {
2146 Visitor->AddStmt(E);
2147 }
2148 for (auto *E : C->destination_exprs()) {
2149 Visitor->AddStmt(E);
2150 }
2151 for (auto *E : C->assignment_ops()) {
2152 Visitor->AddStmt(E);
2153 }
Alexander Musman1bb328c2014-06-04 13:06:39 +00002154}
Alexey Bataev758e55e2013-09-06 18:03:48 +00002155void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002156 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00002157}
Alexey Bataevc5e02582014-06-16 07:08:35 +00002158void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
2159 VisitOMPClauseList(C);
Alexey Bataevf24e7b12015-10-08 09:10:53 +00002160 for (auto *E : C->privates()) {
2161 Visitor->AddStmt(E);
2162 }
Alexey Bataev794ba0d2015-04-10 10:43:45 +00002163 for (auto *E : C->lhs_exprs()) {
2164 Visitor->AddStmt(E);
2165 }
2166 for (auto *E : C->rhs_exprs()) {
2167 Visitor->AddStmt(E);
2168 }
2169 for (auto *E : C->reduction_ops()) {
2170 Visitor->AddStmt(E);
2171 }
Alexey Bataevc5e02582014-06-16 07:08:35 +00002172}
Alexander Musman8dba6642014-04-22 13:09:42 +00002173void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2174 VisitOMPClauseList(C);
Alexey Bataevbd9fec12015-08-18 06:47:21 +00002175 for (const auto *E : C->privates()) {
2176 Visitor->AddStmt(E);
2177 }
Alexander Musman3276a272015-03-21 10:12:56 +00002178 for (const auto *E : C->inits()) {
2179 Visitor->AddStmt(E);
2180 }
2181 for (const auto *E : C->updates()) {
2182 Visitor->AddStmt(E);
2183 }
2184 for (const auto *E : C->finals()) {
2185 Visitor->AddStmt(E);
2186 }
Alexander Musman8dba6642014-04-22 13:09:42 +00002187 Visitor->AddStmt(C->getStep());
Alexander Musman3276a272015-03-21 10:12:56 +00002188 Visitor->AddStmt(C->getCalcStep());
Alexander Musman8dba6642014-04-22 13:09:42 +00002189}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002190void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2191 VisitOMPClauseList(C);
2192 Visitor->AddStmt(C->getAlignment());
2193}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002194void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2195 VisitOMPClauseList(C);
Alexey Bataevf56f98c2015-04-16 05:39:01 +00002196 for (auto *E : C->source_exprs()) {
2197 Visitor->AddStmt(E);
2198 }
2199 for (auto *E : C->destination_exprs()) {
2200 Visitor->AddStmt(E);
2201 }
2202 for (auto *E : C->assignment_ops()) {
2203 Visitor->AddStmt(E);
2204 }
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002205}
Alexey Bataevbae9a792014-06-27 10:37:06 +00002206void
2207OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
2208 VisitOMPClauseList(C);
Alexey Bataeva63048e2015-03-23 06:18:07 +00002209 for (auto *E : C->source_exprs()) {
2210 Visitor->AddStmt(E);
2211 }
2212 for (auto *E : C->destination_exprs()) {
2213 Visitor->AddStmt(E);
2214 }
2215 for (auto *E : C->assignment_ops()) {
2216 Visitor->AddStmt(E);
2217 }
Alexey Bataevbae9a792014-06-27 10:37:06 +00002218}
Alexey Bataev6125da92014-07-21 11:26:11 +00002219void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2220 VisitOMPClauseList(C);
2221}
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +00002222void OMPClauseEnqueue::VisitOMPDependClause(const OMPDependClause *C) {
2223 VisitOMPClauseList(C);
2224}
Kelvin Li0bff7af2015-11-23 05:32:03 +00002225void OMPClauseEnqueue::VisitOMPMapClause(const OMPMapClause *C) {
2226 VisitOMPClauseList(C);
2227}
Carlo Bertollib4adf552016-01-15 18:50:31 +00002228void OMPClauseEnqueue::VisitOMPDistScheduleClause(
2229 const OMPDistScheduleClause *C) {
2230 Visitor->AddStmt(C->getChunkSize());
2231 Visitor->AddStmt(C->getHelperChunkSize());
2232}
Arpith Chacko Jacob3cf89042016-01-26 16:37:23 +00002233void OMPClauseEnqueue::VisitOMPDefaultmapClause(const OMPDefaultmapClause *C) {
2234}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002235}
Alexey Bataev756c1962013-09-24 03:17:45 +00002236
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002237void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2238 unsigned size = WL.size();
2239 OMPClauseEnqueue Visitor(this);
2240 Visitor.Visit(S);
2241 if (size == WL.size())
2242 return;
2243 // Now reverse the entries we just added. This will match the DFS
2244 // ordering performed by the worklist.
2245 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2246 std::reverse(I, E);
2247}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002248void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002249 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2250}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002251void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002252 AddDecl(B->getBlockDecl());
2253}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002254void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002255 EnqueueChildren(E);
2256 AddTypeLoc(E->getTypeSourceInfo());
2257}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002258void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
Pete Cooper57d3f142015-07-30 17:22:52 +00002259 for (auto &I : llvm::reverse(S->body()))
2260 AddStmt(I);
Guy Benyei11169dd2012-12-18 14:30:41 +00002261}
2262void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002263VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002264 AddStmt(S->getSubStmt());
2265 AddDeclarationNameInfo(S);
2266 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2267 AddNestedNameSpecifierLoc(QualifierLoc);
2268}
2269
2270void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002271VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002272 if (E->hasExplicitTemplateArgs())
2273 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002274 AddDeclarationNameInfo(E);
2275 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2276 AddNestedNameSpecifierLoc(QualifierLoc);
2277 if (!E->isImplicitAccess())
2278 AddStmt(E->getBase());
2279}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002280void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002281 // Enqueue the initializer , if any.
2282 AddStmt(E->getInitializer());
2283 // Enqueue the array size, if any.
2284 AddStmt(E->getArraySize());
2285 // Enqueue the allocated type.
2286 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2287 // Enqueue the placement arguments.
2288 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2289 AddStmt(E->getPlacementArg(I-1));
2290}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002291void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002292 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2293 AddStmt(CE->getArg(I-1));
2294 AddStmt(CE->getCallee());
2295 AddStmt(CE->getArg(0));
2296}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002297void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2298 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002299 // Visit the name of the type being destroyed.
2300 AddTypeLoc(E->getDestroyedTypeInfo());
2301 // Visit the scope type that looks disturbingly like the nested-name-specifier
2302 // but isn't.
2303 AddTypeLoc(E->getScopeTypeInfo());
2304 // Visit the nested-name-specifier.
2305 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2306 AddNestedNameSpecifierLoc(QualifierLoc);
2307 // Visit base expression.
2308 AddStmt(E->getBase());
2309}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002310void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2311 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002312 AddTypeLoc(E->getTypeSourceInfo());
2313}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002314void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2315 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002316 EnqueueChildren(E);
2317 AddTypeLoc(E->getTypeSourceInfo());
2318}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002319void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002320 EnqueueChildren(E);
2321 if (E->isTypeOperand())
2322 AddTypeLoc(E->getTypeOperandSourceInfo());
2323}
2324
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002325void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2326 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002327 EnqueueChildren(E);
2328 AddTypeLoc(E->getTypeSourceInfo());
2329}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002330void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002331 EnqueueChildren(E);
2332 if (E->isTypeOperand())
2333 AddTypeLoc(E->getTypeOperandSourceInfo());
2334}
2335
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002336void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002337 EnqueueChildren(S);
2338 AddDecl(S->getExceptionDecl());
2339}
2340
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002341void EnqueueVisitor::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002342 AddStmt(S->getBody());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002343 AddStmt(S->getRangeInit());
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002344 AddDecl(S->getLoopVariable());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002345}
2346
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002347void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002348 if (DR->hasExplicitTemplateArgs())
2349 AddExplicitTemplateArgs(DR->getTemplateArgs(), DR->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002350 WL.push_back(DeclRefExprParts(DR, Parent));
2351}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002352void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2353 const DependentScopeDeclRefExpr *E) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002354 if (E->hasExplicitTemplateArgs())
2355 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002356 AddDeclarationNameInfo(E);
2357 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2358}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002359void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002360 unsigned size = WL.size();
2361 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002362 for (const auto *D : S->decls()) {
2363 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002364 isFirst = false;
2365 }
2366 if (size == WL.size())
2367 return;
2368 // Now reverse the entries we just added. This will match the DFS
2369 // ordering performed by the worklist.
2370 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2371 std::reverse(I, E);
2372}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002373void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002374 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002375 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002376 D = E->designators_rbegin(), DEnd = E->designators_rend();
2377 D != DEnd; ++D) {
2378 if (D->isFieldDesignator()) {
2379 if (FieldDecl *Field = D->getField())
2380 AddMemberRef(Field, D->getFieldLoc());
2381 continue;
2382 }
2383 if (D->isArrayDesignator()) {
2384 AddStmt(E->getArrayIndex(*D));
2385 continue;
2386 }
2387 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2388 AddStmt(E->getArrayRangeEnd(*D));
2389 AddStmt(E->getArrayRangeStart(*D));
2390 }
2391}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002392void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002393 EnqueueChildren(E);
2394 AddTypeLoc(E->getTypeInfoAsWritten());
2395}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002396void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002397 AddStmt(FS->getBody());
2398 AddStmt(FS->getInc());
2399 AddStmt(FS->getCond());
2400 AddDecl(FS->getConditionVariable());
2401 AddStmt(FS->getInit());
2402}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002403void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002404 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2405}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002406void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002407 AddStmt(If->getElse());
2408 AddStmt(If->getThen());
2409 AddStmt(If->getCond());
2410 AddDecl(If->getConditionVariable());
2411}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002412void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002413 // We care about the syntactic form of the initializer list, only.
2414 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2415 IE = Syntactic;
2416 EnqueueChildren(IE);
2417}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002418void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002419 WL.push_back(MemberExprParts(M, Parent));
2420
2421 // If the base of the member access expression is an implicit 'this', don't
2422 // visit it.
2423 // FIXME: If we ever want to show these implicit accesses, this will be
2424 // unfortunate. However, clang_getCursor() relies on this behavior.
Argyrios Kyrtzidis58d0e7a2015-03-13 04:40:07 +00002425 if (M->isImplicitAccess())
2426 return;
2427
2428 // Ignore base anonymous struct/union fields, otherwise they will shadow the
2429 // real field that that we are interested in.
2430 if (auto *SubME = dyn_cast<MemberExpr>(M->getBase())) {
2431 if (auto *FD = dyn_cast_or_null<FieldDecl>(SubME->getMemberDecl())) {
2432 if (FD->isAnonymousStructOrUnion()) {
2433 AddStmt(SubME->getBase());
2434 return;
2435 }
2436 }
2437 }
2438
2439 AddStmt(M->getBase());
Guy Benyei11169dd2012-12-18 14:30:41 +00002440}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002441void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002442 AddTypeLoc(E->getEncodedTypeSourceInfo());
2443}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002444void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002445 EnqueueChildren(M);
2446 AddTypeLoc(M->getClassReceiverTypeInfo());
2447}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002448void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002449 // Visit the components of the offsetof expression.
2450 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002451 const OffsetOfNode &Node = E->getComponent(I-1);
2452 switch (Node.getKind()) {
2453 case OffsetOfNode::Array:
2454 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2455 break;
2456 case OffsetOfNode::Field:
2457 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2458 break;
2459 case OffsetOfNode::Identifier:
2460 case OffsetOfNode::Base:
2461 continue;
2462 }
2463 }
2464 // Visit the type into which we're computing the offset.
2465 AddTypeLoc(E->getTypeSourceInfo());
2466}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002467void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002468 if (E->hasExplicitTemplateArgs())
2469 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002470 WL.push_back(OverloadExprParts(E, Parent));
2471}
2472void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002473 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002474 EnqueueChildren(E);
2475 if (E->isArgumentType())
2476 AddTypeLoc(E->getArgumentTypeInfo());
2477}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002478void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002479 EnqueueChildren(S);
2480}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002481void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002482 AddStmt(S->getBody());
2483 AddStmt(S->getCond());
2484 AddDecl(S->getConditionVariable());
2485}
2486
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002487void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002488 AddStmt(W->getBody());
2489 AddStmt(W->getCond());
2490 AddDecl(W->getConditionVariable());
2491}
2492
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002493void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002494 for (unsigned I = E->getNumArgs(); I > 0; --I)
2495 AddTypeLoc(E->getArg(I-1));
2496}
2497
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002498void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002499 AddTypeLoc(E->getQueriedTypeSourceInfo());
2500}
2501
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002502void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002503 EnqueueChildren(E);
2504}
2505
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002506void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002507 VisitOverloadExpr(U);
2508 if (!U->isImplicitAccess())
2509 AddStmt(U->getBase());
2510}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002511void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002512 AddStmt(E->getSubExpr());
2513 AddTypeLoc(E->getWrittenTypeInfo());
2514}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002515void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002516 WL.push_back(SizeOfPackExprParts(E, Parent));
2517}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002518void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002519 // If the opaque value has a source expression, just transparently
2520 // visit that. This is useful for (e.g.) pseudo-object expressions.
2521 if (Expr *SourceExpr = E->getSourceExpr())
2522 return Visit(SourceExpr);
2523}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002524void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002525 AddStmt(E->getBody());
2526 WL.push_back(LambdaExprParts(E, Parent));
2527}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002528void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002529 // Treat the expression like its syntactic form.
2530 Visit(E->getSyntacticForm());
2531}
2532
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002533void EnqueueVisitor::VisitOMPExecutableDirective(
2534 const OMPExecutableDirective *D) {
2535 EnqueueChildren(D);
2536 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2537 E = D->clauses().end();
2538 I != E; ++I)
2539 EnqueueChildren(*I);
2540}
2541
Alexander Musman3aaab662014-08-19 11:27:13 +00002542void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
2543 VisitOMPExecutableDirective(D);
2544}
2545
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002546void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2547 VisitOMPExecutableDirective(D);
2548}
2549
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002550void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002551 VisitOMPLoopDirective(D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002552}
2553
Alexey Bataevf29276e2014-06-18 04:14:57 +00002554void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002555 VisitOMPLoopDirective(D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002556}
2557
Alexander Musmanf82886e2014-09-18 05:12:34 +00002558void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
2559 VisitOMPLoopDirective(D);
2560}
2561
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002562void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2563 VisitOMPExecutableDirective(D);
2564}
2565
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002566void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2567 VisitOMPExecutableDirective(D);
2568}
2569
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002570void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2571 VisitOMPExecutableDirective(D);
2572}
2573
Alexander Musman80c22892014-07-17 08:54:58 +00002574void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2575 VisitOMPExecutableDirective(D);
2576}
2577
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002578void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2579 VisitOMPExecutableDirective(D);
2580 AddDeclarationNameInfo(D);
2581}
2582
Alexey Bataev4acb8592014-07-07 13:01:15 +00002583void
2584EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002585 VisitOMPLoopDirective(D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002586}
2587
Alexander Musmane4e893b2014-09-23 09:33:00 +00002588void EnqueueVisitor::VisitOMPParallelForSimdDirective(
2589 const OMPParallelForSimdDirective *D) {
2590 VisitOMPLoopDirective(D);
2591}
2592
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002593void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2594 const OMPParallelSectionsDirective *D) {
2595 VisitOMPExecutableDirective(D);
2596}
2597
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002598void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2599 VisitOMPExecutableDirective(D);
2600}
2601
Alexey Bataev68446b72014-07-18 07:47:19 +00002602void
2603EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2604 VisitOMPExecutableDirective(D);
2605}
2606
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002607void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2608 VisitOMPExecutableDirective(D);
2609}
2610
Alexey Bataev2df347a2014-07-18 10:17:07 +00002611void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2612 VisitOMPExecutableDirective(D);
2613}
2614
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002615void EnqueueVisitor::VisitOMPTaskgroupDirective(
2616 const OMPTaskgroupDirective *D) {
2617 VisitOMPExecutableDirective(D);
2618}
2619
Alexey Bataev6125da92014-07-21 11:26:11 +00002620void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2621 VisitOMPExecutableDirective(D);
2622}
2623
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002624void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2625 VisitOMPExecutableDirective(D);
2626}
2627
Alexey Bataev0162e452014-07-22 10:10:35 +00002628void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2629 VisitOMPExecutableDirective(D);
2630}
2631
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002632void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
2633 VisitOMPExecutableDirective(D);
2634}
2635
Michael Wong65f367f2015-07-21 13:44:28 +00002636void EnqueueVisitor::VisitOMPTargetDataDirective(const
2637 OMPTargetDataDirective *D) {
2638 VisitOMPExecutableDirective(D);
2639}
2640
Samuel Antaodf67fc42016-01-19 19:15:56 +00002641void EnqueueVisitor::VisitOMPTargetEnterDataDirective(
2642 const OMPTargetEnterDataDirective *D) {
2643 VisitOMPExecutableDirective(D);
2644}
2645
Samuel Antao72590762016-01-19 20:04:50 +00002646void EnqueueVisitor::VisitOMPTargetExitDataDirective(
2647 const OMPTargetExitDataDirective *D) {
2648 VisitOMPExecutableDirective(D);
2649}
2650
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00002651void EnqueueVisitor::VisitOMPTargetParallelDirective(
2652 const OMPTargetParallelDirective *D) {
2653 VisitOMPExecutableDirective(D);
2654}
2655
Alexey Bataev13314bf2014-10-09 04:18:56 +00002656void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {
2657 VisitOMPExecutableDirective(D);
2658}
2659
Alexey Bataev6d4ed052015-07-01 06:57:41 +00002660void EnqueueVisitor::VisitOMPCancellationPointDirective(
2661 const OMPCancellationPointDirective *D) {
2662 VisitOMPExecutableDirective(D);
2663}
2664
Alexey Bataev80909872015-07-02 11:25:17 +00002665void EnqueueVisitor::VisitOMPCancelDirective(const OMPCancelDirective *D) {
2666 VisitOMPExecutableDirective(D);
2667}
2668
Alexey Bataev49f6e782015-12-01 04:18:41 +00002669void EnqueueVisitor::VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *D) {
2670 VisitOMPLoopDirective(D);
2671}
2672
Alexey Bataev0a6ed842015-12-03 09:40:15 +00002673void EnqueueVisitor::VisitOMPTaskLoopSimdDirective(
2674 const OMPTaskLoopSimdDirective *D) {
2675 VisitOMPLoopDirective(D);
2676}
2677
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00002678void EnqueueVisitor::VisitOMPDistributeDirective(
2679 const OMPDistributeDirective *D) {
2680 VisitOMPLoopDirective(D);
2681}
2682
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002683void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002684 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2685}
2686
2687bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2688 if (RegionOfInterest.isValid()) {
2689 SourceRange Range = getRawCursorExtent(C);
2690 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2691 return false;
2692 }
2693 return true;
2694}
2695
2696bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2697 while (!WL.empty()) {
2698 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002699 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002700
2701 // Set the Parent field, then back to its old value once we're done.
2702 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2703
2704 switch (LI.getKind()) {
2705 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002706 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002707 if (!D)
2708 continue;
2709
2710 // For now, perform default visitation for Decls.
2711 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2712 cast<DeclVisit>(&LI)->isFirst())))
2713 return true;
2714
2715 continue;
2716 }
2717 case VisitorJob::ExplicitTemplateArgsVisitKind: {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002718 for (const TemplateArgumentLoc &Arg :
2719 *cast<ExplicitTemplateArgsVisit>(&LI)) {
2720 if (VisitTemplateArgumentLoc(Arg))
Guy Benyei11169dd2012-12-18 14:30:41 +00002721 return true;
2722 }
2723 continue;
2724 }
2725 case VisitorJob::TypeLocVisitKind: {
2726 // Perform default visitation for TypeLocs.
2727 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2728 return true;
2729 continue;
2730 }
2731 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002732 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002733 if (LabelStmt *stmt = LS->getStmt()) {
2734 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2735 TU))) {
2736 return true;
2737 }
2738 }
2739 continue;
2740 }
2741
2742 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2743 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2744 if (VisitNestedNameSpecifierLoc(V->get()))
2745 return true;
2746 continue;
2747 }
2748
2749 case VisitorJob::DeclarationNameInfoVisitKind: {
2750 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2751 ->get()))
2752 return true;
2753 continue;
2754 }
2755 case VisitorJob::MemberRefVisitKind: {
2756 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2757 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2758 return true;
2759 continue;
2760 }
2761 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002762 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002763 if (!S)
2764 continue;
2765
2766 // Update the current cursor.
2767 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2768 if (!IsInRegionOfInterest(Cursor))
2769 continue;
2770 switch (Visitor(Cursor, Parent, ClientData)) {
2771 case CXChildVisit_Break: return true;
2772 case CXChildVisit_Continue: break;
2773 case CXChildVisit_Recurse:
2774 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002775 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002776 EnqueueWorkList(WL, S);
2777 break;
2778 }
2779 continue;
2780 }
2781 case VisitorJob::MemberExprPartsKind: {
2782 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002783 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002784
2785 // Visit the nested-name-specifier
2786 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2787 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2788 return true;
2789
2790 // Visit the declaration name.
2791 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2792 return true;
2793
2794 // Visit the explicitly-specified template arguments, if any.
2795 if (M->hasExplicitTemplateArgs()) {
2796 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2797 *ArgEnd = Arg + M->getNumTemplateArgs();
2798 Arg != ArgEnd; ++Arg) {
2799 if (VisitTemplateArgumentLoc(*Arg))
2800 return true;
2801 }
2802 }
2803 continue;
2804 }
2805 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002806 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002807 // Visit nested-name-specifier, if present.
2808 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2809 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2810 return true;
2811 // Visit declaration name.
2812 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2813 return true;
2814 continue;
2815 }
2816 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002817 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002818 // Visit the nested-name-specifier.
2819 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2820 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2821 return true;
2822 // Visit the declaration name.
2823 if (VisitDeclarationNameInfo(O->getNameInfo()))
2824 return true;
2825 // Visit the overloaded declaration reference.
2826 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2827 return true;
2828 continue;
2829 }
2830 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002831 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002832 NamedDecl *Pack = E->getPack();
2833 if (isa<TemplateTypeParmDecl>(Pack)) {
2834 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2835 E->getPackLoc(), TU)))
2836 return true;
2837
2838 continue;
2839 }
2840
2841 if (isa<TemplateTemplateParmDecl>(Pack)) {
2842 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2843 E->getPackLoc(), TU)))
2844 return true;
2845
2846 continue;
2847 }
2848
2849 // Non-type template parameter packs and function parameter packs are
2850 // treated like DeclRefExpr cursors.
2851 continue;
2852 }
2853
2854 case VisitorJob::LambdaExprPartsKind: {
2855 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002856 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002857 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2858 CEnd = E->explicit_capture_end();
2859 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002860 // FIXME: Lambda init-captures.
2861 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002862 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002863
Guy Benyei11169dd2012-12-18 14:30:41 +00002864 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2865 C->getLocation(),
2866 TU)))
2867 return true;
2868 }
2869
2870 // Visit parameters and return type, if present.
2871 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2872 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2873 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2874 // Visit the whole type.
2875 if (Visit(TL))
2876 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002877 } else if (FunctionProtoTypeLoc Proto =
2878 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002879 if (E->hasExplicitParameters()) {
2880 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002881 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2882 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002883 return true;
2884 } else {
2885 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002886 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002887 return true;
2888 }
2889 }
2890 }
2891 break;
2892 }
2893
2894 case VisitorJob::PostChildrenVisitKind:
2895 if (PostChildrenVisitor(Parent, ClientData))
2896 return true;
2897 break;
2898 }
2899 }
2900 return false;
2901}
2902
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002903bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002904 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002905 if (!WorkListFreeList.empty()) {
2906 WL = WorkListFreeList.back();
2907 WL->clear();
2908 WorkListFreeList.pop_back();
2909 }
2910 else {
2911 WL = new VisitorWorkList();
2912 WorkListCache.push_back(WL);
2913 }
2914 EnqueueWorkList(*WL, S);
2915 bool result = RunVisitorWorkList(*WL);
2916 WorkListFreeList.push_back(WL);
2917 return result;
2918}
2919
2920namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002921typedef SmallVector<SourceRange, 4> RefNamePieces;
James Y Knight04ec5bf2015-12-24 02:59:37 +00002922RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2923 const DeclarationNameInfo &NI, SourceRange QLoc,
2924 const SourceRange *TemplateArgsLoc = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002925 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2926 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2927 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2928
2929 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2930
2931 RefNamePieces Pieces;
2932
2933 if (WantQualifier && QLoc.isValid())
2934 Pieces.push_back(QLoc);
2935
2936 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2937 Pieces.push_back(NI.getLoc());
James Y Knight04ec5bf2015-12-24 02:59:37 +00002938
2939 if (WantTemplateArgs && TemplateArgsLoc && TemplateArgsLoc->isValid())
2940 Pieces.push_back(*TemplateArgsLoc);
2941
Guy Benyei11169dd2012-12-18 14:30:41 +00002942 if (Kind == DeclarationName::CXXOperatorName) {
2943 Pieces.push_back(SourceLocation::getFromRawEncoding(
2944 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2945 Pieces.push_back(SourceLocation::getFromRawEncoding(
2946 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2947 }
2948
2949 if (WantSinglePiece) {
2950 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2951 Pieces.clear();
2952 Pieces.push_back(R);
2953 }
2954
2955 return Pieces;
2956}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002957}
Guy Benyei11169dd2012-12-18 14:30:41 +00002958
2959//===----------------------------------------------------------------------===//
2960// Misc. API hooks.
2961//===----------------------------------------------------------------------===//
2962
Chad Rosier05c71aa2013-03-27 18:28:23 +00002963static void fatal_error_handler(void *user_data, const std::string& reason,
2964 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002965 // Write the result out to stderr avoiding errs() because raw_ostreams can
2966 // call report_fatal_error.
2967 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2968 ::abort();
2969}
2970
Chandler Carruth66660742014-06-27 16:37:27 +00002971namespace {
2972struct RegisterFatalErrorHandler {
2973 RegisterFatalErrorHandler() {
2974 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2975 }
2976};
2977}
2978
2979static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
2980
Guy Benyei11169dd2012-12-18 14:30:41 +00002981extern "C" {
2982CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2983 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002984 // We use crash recovery to make some of our APIs more reliable, implicitly
2985 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002986 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2987 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002988
Chandler Carruth66660742014-06-27 16:37:27 +00002989 // Look through the managed static to trigger construction of the managed
2990 // static which registers our fatal error handler. This ensures it is only
2991 // registered once.
2992 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00002993
Adrian Prantlbc068582015-07-08 01:00:30 +00002994 // Initialize targets for clang module support.
2995 llvm::InitializeAllTargets();
2996 llvm::InitializeAllTargetMCs();
2997 llvm::InitializeAllAsmPrinters();
2998 llvm::InitializeAllAsmParsers();
2999
Adrian Prantlfb2398d2015-07-17 01:19:54 +00003000 CIndexer *CIdxr = new CIndexer();
3001
Guy Benyei11169dd2012-12-18 14:30:41 +00003002 if (excludeDeclarationsFromPCH)
3003 CIdxr->setOnlyLocalDecls();
3004 if (displayDiagnostics)
3005 CIdxr->setDisplayDiagnostics();
3006
3007 if (getenv("LIBCLANG_BGPRIO_INDEX"))
3008 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
3009 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
3010 if (getenv("LIBCLANG_BGPRIO_EDIT"))
3011 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
3012 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
3013
3014 return CIdxr;
3015}
3016
3017void clang_disposeIndex(CXIndex CIdx) {
3018 if (CIdx)
3019 delete static_cast<CIndexer *>(CIdx);
3020}
3021
3022void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
3023 if (CIdx)
3024 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
3025}
3026
3027unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
3028 if (CIdx)
3029 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
3030 return 0;
3031}
3032
3033void clang_toggleCrashRecovery(unsigned isEnabled) {
3034 if (isEnabled)
3035 llvm::CrashRecoveryContext::Enable();
3036 else
3037 llvm::CrashRecoveryContext::Disable();
3038}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003039
Guy Benyei11169dd2012-12-18 14:30:41 +00003040CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
3041 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003042 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003043 enum CXErrorCode Result =
3044 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00003045 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003046 assert((TU && Result == CXError_Success) ||
3047 (!TU && Result != CXError_Success));
3048 return TU;
3049}
3050
3051enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
3052 const char *ast_filename,
3053 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003054 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00003055 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003056
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003057 if (!CIdx || !ast_filename || !out_TU)
3058 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00003059
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00003060 LOG_FUNC_SECTION {
3061 *Log << ast_filename;
3062 }
3063
Guy Benyei11169dd2012-12-18 14:30:41 +00003064 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3065 FileSystemOptions FileSystemOpts;
3066
Justin Bognerd512c1e2014-10-15 00:33:06 +00003067 IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
3068 CompilerInstance::createDiagnostics(new DiagnosticOptions());
David Blaikie6f7382d2014-08-10 19:08:04 +00003069 std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
Adrian Prantlfb2398d2015-07-17 01:19:54 +00003070 ast_filename, CXXIdx->getPCHContainerOperations()->getRawReader(), Diags,
Adrian Prantl6b21ab22015-08-27 19:46:20 +00003071 FileSystemOpts, /*UseDebugInfo=*/false,
3072 CXXIdx->getOnlyLocalDecls(), None,
David Blaikie6f7382d2014-08-10 19:08:04 +00003073 /*CaptureDiagnostics=*/true,
3074 /*AllowPCHWithCompilerErrors=*/true,
3075 /*UserFilesAreVolatile=*/true);
3076 *out_TU = MakeCXTranslationUnit(CXXIdx, AU.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003077 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003078}
3079
3080unsigned clang_defaultEditingTranslationUnitOptions() {
3081 return CXTranslationUnit_PrecompiledPreamble |
3082 CXTranslationUnit_CacheCompletionResults;
3083}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003084
Guy Benyei11169dd2012-12-18 14:30:41 +00003085CXTranslationUnit
3086clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
3087 const char *source_filename,
3088 int num_command_line_args,
3089 const char * const *command_line_args,
3090 unsigned num_unsaved_files,
3091 struct CXUnsavedFile *unsaved_files) {
3092 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
3093 return clang_parseTranslationUnit(CIdx, source_filename,
3094 command_line_args, num_command_line_args,
3095 unsaved_files, num_unsaved_files,
3096 Options);
3097}
3098
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003099static CXErrorCode
3100clang_parseTranslationUnit_Impl(CXIndex CIdx, const char *source_filename,
3101 const char *const *command_line_args,
3102 int num_command_line_args,
3103 ArrayRef<CXUnsavedFile> unsaved_files,
3104 unsigned options, CXTranslationUnit *out_TU) {
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003105 // Set up the initial return values.
3106 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00003107 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003108
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003109 // Check arguments.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003110 if (!CIdx || !out_TU)
3111 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003112
Guy Benyei11169dd2012-12-18 14:30:41 +00003113 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3114
3115 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3116 setThreadBackgroundPriority();
3117
3118 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
Benjamin Kramer5c248d82015-12-15 09:30:31 +00003119 bool CreatePreambleOnFirstParse =
3120 options & CXTranslationUnit_CreatePreambleOnFirstParse;
Guy Benyei11169dd2012-12-18 14:30:41 +00003121 // FIXME: Add a flag for modules.
3122 TranslationUnitKind TUKind
3123 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00003124 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00003125 = options & CXTranslationUnit_CacheCompletionResults;
3126 bool IncludeBriefCommentsInCodeCompletion
3127 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
3128 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
3129 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
3130
3131 // Configure the diagnostics.
3132 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00003133 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00003134
3135 // Recover resources if we crash before exiting this function.
3136 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
3137 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00003138 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00003139
Ahmed Charlesb8984322014-03-07 20:03:18 +00003140 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3141 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003142
3143 // Recover resources if we crash before exiting this function.
3144 llvm::CrashRecoveryContextCleanupRegistrar<
3145 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3146
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003147 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003148 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003149 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003150 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003151 }
3152
Ahmed Charlesb8984322014-03-07 20:03:18 +00003153 std::unique_ptr<std::vector<const char *>> Args(
3154 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003155
3156 // Recover resources if we crash before exiting this method.
3157 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
3158 ArgsCleanup(Args.get());
3159
3160 // Since the Clang C library is primarily used by batch tools dealing with
3161 // (often very broken) source code, where spell-checking can have a
3162 // significant negative impact on performance (particularly when
3163 // precompiled headers are involved), we disable it by default.
3164 // Only do this if we haven't found a spell-checking-related argument.
3165 bool FoundSpellCheckingArgument = false;
3166 for (int I = 0; I != num_command_line_args; ++I) {
3167 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
3168 strcmp(command_line_args[I], "-fspell-checking") == 0) {
3169 FoundSpellCheckingArgument = true;
3170 break;
3171 }
3172 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003173 Args->insert(Args->end(), command_line_args,
3174 command_line_args + num_command_line_args);
3175
Benjamin Kramerc02670e2015-11-18 16:14:27 +00003176 if (!FoundSpellCheckingArgument)
3177 Args->insert(Args->begin() + 1, "-fno-spell-checking");
3178
Guy Benyei11169dd2012-12-18 14:30:41 +00003179 // The 'source_filename' argument is optional. If the caller does not
3180 // specify it then it is assumed that the source file is specified
3181 // in the actual argument list.
3182 // Put the source file after command_line_args otherwise if '-x' flag is
3183 // present it will be unused.
3184 if (source_filename)
3185 Args->push_back(source_filename);
3186
3187 // Do we need the detailed preprocessing record?
3188 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
3189 Args->push_back("-Xclang");
3190 Args->push_back("-detailed-preprocessing-record");
3191 }
3192
3193 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00003194 std::unique_ptr<ASTUnit> ErrUnit;
Benjamin Kramer5c248d82015-12-15 09:30:31 +00003195 // Unless the user specified that they want the preamble on the first parse
3196 // set it up to be created on the first reparse. This makes the first parse
3197 // faster, trading for a slower (first) reparse.
3198 unsigned PrecompilePreambleAfterNParses =
3199 !PrecompilePreamble ? 0 : 2 - CreatePreambleOnFirstParse;
Ahmed Charlesb8984322014-03-07 20:03:18 +00003200 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003201 Args->data(), Args->data() + Args->size(),
3202 CXXIdx->getPCHContainerOperations(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00003203 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
3204 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
Benjamin Kramer5c248d82015-12-15 09:30:31 +00003205 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreambleAfterNParses,
3206 TUKind, CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
Ahmed Charlesb8984322014-03-07 20:03:18 +00003207 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
Argyrios Kyrtzidisa3e2ff12015-11-20 03:36:21 +00003208 /*UserFilesAreVolatile=*/true, ForSerialization,
3209 CXXIdx->getPCHContainerOperations()->getRawReader().getFormat(),
3210 &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00003211
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003212 // Early failures in LoadFromCommandLine may return with ErrUnit unset.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003213 if (!Unit && !ErrUnit)
3214 return CXError_ASTReadError;
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003215
Guy Benyei11169dd2012-12-18 14:30:41 +00003216 if (NumErrors != Diags->getClient()->getNumErrors()) {
3217 // Make sure to check that 'Unit' is non-NULL.
3218 if (CXXIdx->getDisplayDiagnostics())
3219 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
3220 }
3221
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003222 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get()))
3223 return CXError_ASTReadError;
3224
3225 *out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
3226 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003227}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003228
3229CXTranslationUnit
3230clang_parseTranslationUnit(CXIndex CIdx,
3231 const char *source_filename,
3232 const char *const *command_line_args,
3233 int num_command_line_args,
3234 struct CXUnsavedFile *unsaved_files,
3235 unsigned num_unsaved_files,
3236 unsigned options) {
3237 CXTranslationUnit TU;
3238 enum CXErrorCode Result = clang_parseTranslationUnit2(
3239 CIdx, source_filename, command_line_args, num_command_line_args,
3240 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00003241 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003242 assert((TU && Result == CXError_Success) ||
3243 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003244 return TU;
3245}
3246
3247enum CXErrorCode clang_parseTranslationUnit2(
Benjamin Kramerc02670e2015-11-18 16:14:27 +00003248 CXIndex CIdx, const char *source_filename,
3249 const char *const *command_line_args, int num_command_line_args,
3250 struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
3251 unsigned options, CXTranslationUnit *out_TU) {
3252 SmallVector<const char *, 4> Args;
3253 Args.push_back("clang");
3254 Args.append(command_line_args, command_line_args + num_command_line_args);
3255 return clang_parseTranslationUnit2FullArgv(
3256 CIdx, source_filename, Args.data(), Args.size(), unsaved_files,
3257 num_unsaved_files, options, out_TU);
3258}
3259
3260enum CXErrorCode clang_parseTranslationUnit2FullArgv(
3261 CXIndex CIdx, const char *source_filename,
3262 const char *const *command_line_args, int num_command_line_args,
3263 struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
3264 unsigned options, CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003265 LOG_FUNC_SECTION {
3266 *Log << source_filename << ": ";
3267 for (int i = 0; i != num_command_line_args; ++i)
3268 *Log << command_line_args[i] << " ";
3269 }
3270
Alp Toker9d85b182014-07-07 01:23:14 +00003271 if (num_unsaved_files && !unsaved_files)
3272 return CXError_InvalidArguments;
3273
Alp Toker5c532982014-07-07 22:42:03 +00003274 CXErrorCode result = CXError_Failure;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003275 auto ParseTranslationUnitImpl = [=, &result] {
3276 result = clang_parseTranslationUnit_Impl(
3277 CIdx, source_filename, command_line_args, num_command_line_args,
3278 llvm::makeArrayRef(unsaved_files, num_unsaved_files), options, out_TU);
3279 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003280 llvm::CrashRecoveryContext CRC;
3281
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003282 if (!RunSafely(CRC, ParseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003283 fprintf(stderr, "libclang: crash detected during parsing: {\n");
3284 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3285 fprintf(stderr, " 'command_line_args' : [");
3286 for (int i = 0; i != num_command_line_args; ++i) {
3287 if (i)
3288 fprintf(stderr, ", ");
3289 fprintf(stderr, "'%s'", command_line_args[i]);
3290 }
3291 fprintf(stderr, "],\n");
3292 fprintf(stderr, " 'unsaved_files' : [");
3293 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3294 if (i)
3295 fprintf(stderr, ", ");
3296 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3297 unsaved_files[i].Length);
3298 }
3299 fprintf(stderr, "],\n");
3300 fprintf(stderr, " 'options' : %d,\n", options);
3301 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003302
3303 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003304 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003305 if (CXTranslationUnit *TU = out_TU)
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003306 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003307 }
Alp Toker5c532982014-07-07 22:42:03 +00003308
3309 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003310}
3311
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003312CXString clang_Type_getObjCEncoding(CXType CT) {
3313 CXTranslationUnit tu = static_cast<CXTranslationUnit>(CT.data[1]);
3314 ASTContext &Ctx = getASTUnit(tu)->getASTContext();
3315 std::string encoding;
3316 Ctx.getObjCEncodingForType(QualType::getFromOpaquePtr(CT.data[0]),
3317 encoding);
3318
3319 return cxstring::createDup(encoding);
3320}
3321
3322static const IdentifierInfo *getMacroIdentifier(CXCursor C) {
3323 if (C.kind == CXCursor_MacroDefinition) {
3324 if (const MacroDefinitionRecord *MDR = getCursorMacroDefinition(C))
3325 return MDR->getName();
3326 } else if (C.kind == CXCursor_MacroExpansion) {
3327 MacroExpansionCursor ME = getCursorMacroExpansion(C);
3328 return ME.getName();
3329 }
3330 return nullptr;
3331}
3332
3333unsigned clang_Cursor_isMacroFunctionLike(CXCursor C) {
3334 const IdentifierInfo *II = getMacroIdentifier(C);
3335 if (!II) {
3336 return false;
3337 }
3338 ASTUnit *ASTU = getCursorASTUnit(C);
3339 Preprocessor &PP = ASTU->getPreprocessor();
3340 if (const MacroInfo *MI = PP.getMacroInfo(II))
3341 return MI->isFunctionLike();
3342 return false;
3343}
3344
3345unsigned clang_Cursor_isMacroBuiltin(CXCursor C) {
3346 const IdentifierInfo *II = getMacroIdentifier(C);
3347 if (!II) {
3348 return false;
3349 }
3350 ASTUnit *ASTU = getCursorASTUnit(C);
3351 Preprocessor &PP = ASTU->getPreprocessor();
3352 if (const MacroInfo *MI = PP.getMacroInfo(II))
3353 return MI->isBuiltinMacro();
3354 return false;
3355}
3356
3357unsigned clang_Cursor_isFunctionInlined(CXCursor C) {
3358 const Decl *D = getCursorDecl(C);
3359 const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D);
3360 if (!FD) {
3361 return false;
3362 }
3363 return FD->isInlined();
3364}
3365
3366static StringLiteral* getCFSTR_value(CallExpr *callExpr) {
3367 if (callExpr->getNumArgs() != 1) {
3368 return nullptr;
3369 }
3370
3371 StringLiteral *S = nullptr;
3372 auto *arg = callExpr->getArg(0);
3373 if (arg->getStmtClass() == Stmt::ImplicitCastExprClass) {
3374 ImplicitCastExpr *I = static_cast<ImplicitCastExpr *>(arg);
3375 auto *subExpr = I->getSubExprAsWritten();
3376
3377 if(subExpr->getStmtClass() != Stmt::StringLiteralClass){
3378 return nullptr;
3379 }
3380
3381 S = static_cast<StringLiteral *>(I->getSubExprAsWritten());
3382 } else if (arg->getStmtClass() == Stmt::StringLiteralClass) {
3383 S = static_cast<StringLiteral *>(callExpr->getArg(0));
3384 } else {
3385 return nullptr;
3386 }
3387 return S;
3388}
3389
3390typedef struct {
3391 CXEvalResultKind EvalType;
3392 union {
3393 int intVal;
3394 double floatVal;
3395 char *stringVal;
3396 } EvalData;
3397} ExprEvalResult;
3398
3399void clang_EvalResult_dispose(CXEvalResult E) {
3400 ExprEvalResult *ER = (ExprEvalResult *)E;
3401 if (ER) {
3402 CXEvalResultKind evalType = ER->EvalType;
3403
3404 if (evalType != CXEval_UnExposed && evalType != CXEval_Float &&
3405 evalType != CXEval_Int && ER->EvalData.stringVal) {
3406 free((void *) ER->EvalData.stringVal);
3407 }
3408 free((void *)ER);
3409 }
3410}
3411
3412CXEvalResultKind clang_EvalResult_getKind(CXEvalResult E) {
3413 if (!E) {
3414 return CXEval_UnExposed;
3415 }
3416 return ((ExprEvalResult *)E)->EvalType;
3417}
3418
3419int clang_EvalResult_getAsInt(CXEvalResult E) {
3420 if (!E) {
3421 return 0;
3422 }
3423 return ((ExprEvalResult *)E)->EvalData.intVal;
3424}
3425
3426double clang_EvalResult_getAsDouble(CXEvalResult E) {
3427 if (!E) {
3428 return 0;
3429 }
3430 return ((ExprEvalResult *)E)->EvalData.floatVal;
3431}
3432
3433const char* clang_EvalResult_getAsStr(CXEvalResult E) {
3434 if (!E) {
3435 return nullptr;
3436 }
3437 return ((ExprEvalResult *)E)->EvalData.stringVal;
3438}
3439
3440static const ExprEvalResult* evaluateExpr(Expr *expr, CXCursor C) {
3441 Expr::EvalResult ER;
3442 ASTContext &ctx = getCursorContext(C);
3443 if (!expr) {
3444 return nullptr;
3445 }
3446 expr = expr->IgnoreParens();
3447 bool res = expr->EvaluateAsRValue(ER, ctx);
3448 QualType rettype;
3449 CallExpr *callExpr;
3450 ExprEvalResult *result = (ExprEvalResult *) malloc(sizeof(ExprEvalResult));
3451 if (!result) {
3452 return nullptr;
3453 }
3454 result->EvalType = CXEval_UnExposed;
3455
3456 if (res) {
3457
3458 if (ER.Val.isInt()) {
3459 result->EvalType = CXEval_Int;
3460 result->EvalData.intVal = ER.Val.getInt().getExtValue();
3461 return result;
3462 } else if (ER.Val.isFloat()) {
3463
3464 llvm::SmallVector<char, 100> Buffer;
3465 ER.Val.getFloat().toString(Buffer);
3466 std::string floatStr(Buffer.data(), Buffer.size());
3467 result->EvalType = CXEval_Float;
3468 bool ignored;
3469 llvm::APFloat apFloat = ER.Val.getFloat();
3470 apFloat.convert(llvm::APFloat::IEEEdouble,
3471 llvm::APFloat::rmNearestTiesToEven, &ignored);
3472 result->EvalData.floatVal = apFloat.convertToDouble();
3473 return result;
3474
3475 } else if (expr->getStmtClass() == Stmt::ImplicitCastExprClass) {
3476
3477 const ImplicitCastExpr *I = dyn_cast<ImplicitCastExpr>(expr);
3478 auto *subExpr = I->getSubExprAsWritten();
3479 if (subExpr->getStmtClass() == Stmt::StringLiteralClass ||
3480 subExpr->getStmtClass() == Stmt::ObjCStringLiteralClass) {
3481
3482 const StringLiteral *StrE = nullptr;
3483 const ObjCStringLiteral *ObjCExpr;
3484 ObjCExpr = dyn_cast<ObjCStringLiteral>(subExpr);
3485
3486 if (ObjCExpr) {
3487 StrE = ObjCExpr->getString();
3488 result->EvalType = CXEval_ObjCStrLiteral;
3489 } else {
3490 StrE = cast<StringLiteral>(I->getSubExprAsWritten());
3491 result->EvalType = CXEval_StrLiteral;
3492 }
3493
3494 std::string strRef(StrE->getString().str());
3495 result->EvalData.stringVal = (char *)malloc(strRef.size()+1);
3496 strncpy((char*)result->EvalData.stringVal, strRef.c_str(),
3497 strRef.size());
3498 result->EvalData.stringVal[strRef.size()] = '\0';
3499 return result;
3500 }
3501
3502 } else if (expr->getStmtClass() == Stmt::ObjCStringLiteralClass ||
3503 expr->getStmtClass() == Stmt::StringLiteralClass) {
3504
3505 const StringLiteral *StrE = nullptr;
3506 const ObjCStringLiteral *ObjCExpr;
3507 ObjCExpr = dyn_cast<ObjCStringLiteral>(expr);
3508
3509 if (ObjCExpr) {
3510 StrE = ObjCExpr->getString();
3511 result->EvalType = CXEval_ObjCStrLiteral;
3512 } else {
3513 StrE = cast<StringLiteral>(expr);
3514 result->EvalType = CXEval_StrLiteral;
3515 }
3516
3517 std::string strRef(StrE->getString().str());
3518 result->EvalData.stringVal = (char *)malloc(strRef.size()+1);
3519 strncpy((char*)result->EvalData.stringVal, strRef.c_str(),
3520 strRef.size());
3521 result->EvalData.stringVal[strRef.size()] = '\0';
3522 return result;
3523
3524 } else if (expr->getStmtClass() == Stmt::CStyleCastExprClass) {
3525
3526 CStyleCastExpr *CC = static_cast<CStyleCastExpr *>(expr);
3527
3528 rettype = CC->getType();
3529 if (rettype.getAsString() == "CFStringRef" &&
3530 CC->getSubExpr()->getStmtClass() == Stmt::CallExprClass) {
3531
3532 callExpr = static_cast<CallExpr *>(CC->getSubExpr());
3533 StringLiteral* S = getCFSTR_value(callExpr);
3534 if (S) {
3535 std::string strLiteral(S->getString().str());
3536 result->EvalType = CXEval_CFStr;
3537
3538 result->EvalData.stringVal = (char *)malloc(strLiteral.size()+1);
3539 strncpy((char*)result->EvalData.stringVal, strLiteral.c_str(),
3540 strLiteral.size());
3541 result->EvalData.stringVal[strLiteral.size()] = '\0';
3542 return result;
3543 }
3544 }
3545
3546 } else if (expr->getStmtClass() == Stmt::CallExprClass) {
3547
3548 callExpr = static_cast<CallExpr *>(expr);
3549 rettype = callExpr->getCallReturnType(ctx);
3550
3551 if (rettype->isVectorType() || callExpr->getNumArgs() > 1) {
3552 return nullptr;
3553 }
3554 if (rettype->isIntegralType(ctx) || rettype->isRealFloatingType()) {
3555 if(callExpr->getNumArgs() == 1 &&
3556 !callExpr->getArg(0)->getType()->isIntegralType(ctx)){
3557
3558 return nullptr;
3559 }
3560 } else if(rettype.getAsString() == "CFStringRef") {
3561
3562 StringLiteral* S = getCFSTR_value(callExpr);
3563 if (S) {
3564 std::string strLiteral(S->getString().str());
3565 result->EvalType = CXEval_CFStr;
3566 result->EvalData.stringVal = (char *)malloc(strLiteral.size()+1);
3567 strncpy((char*)result->EvalData.stringVal, strLiteral.c_str(),
3568 strLiteral.size());
3569 result->EvalData.stringVal[strLiteral.size()] = '\0';
3570 return result;
3571 }
3572 }
3573
3574 } else if (expr->getStmtClass() == Stmt::DeclRefExprClass) {
3575
3576 DeclRefExpr *D = static_cast<DeclRefExpr *>(expr);
3577 ValueDecl *V = D->getDecl();
3578 if (V->getKind() == Decl::Function) {
3579 std::string strName(V->getNameAsString());
3580 result->EvalType = CXEval_Other;
3581 result->EvalData.stringVal = (char *)malloc(strName.size()+1);
3582 strncpy((char*)result->EvalData.stringVal, strName.c_str(),
3583 strName.size());
3584 result->EvalData.stringVal[strName.size()] = '\0';
3585 return result;
3586 }
3587 }
3588
3589 }
3590
3591 clang_EvalResult_dispose((CXEvalResult *)result);
3592 return nullptr;
3593}
3594
3595CXEvalResult clang_Cursor_Evaluate(CXCursor C) {
3596 const Decl *D = getCursorDecl(C);
3597 if (D) {
3598 const Expr *expr = nullptr;
3599 if (auto *Var = dyn_cast<VarDecl>(D)) {
3600 expr = Var->getInit();
3601 } else if (auto *Field = dyn_cast<FieldDecl>(D)) {
3602 expr = Field->getInClassInitializer();
3603 }
3604 if (expr)
Aaron Ballman01dc1572016-01-20 15:25:30 +00003605 return const_cast<CXEvalResult>(reinterpret_cast<const void *>(
3606 evaluateExpr(const_cast<Expr *>(expr), C)));
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003607 return nullptr;
3608 }
3609
3610 const CompoundStmt *compoundStmt = dyn_cast_or_null<CompoundStmt>(getCursorStmt(C));
3611 if (compoundStmt) {
3612 Expr *expr = nullptr;
3613 for (auto *bodyIterator : compoundStmt->body()) {
3614 if ((expr = dyn_cast<Expr>(bodyIterator))) {
3615 break;
3616 }
3617 }
3618 if (expr)
Aaron Ballman01dc1572016-01-20 15:25:30 +00003619 return const_cast<CXEvalResult>(
3620 reinterpret_cast<const void *>(evaluateExpr(expr, C)));
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003621 }
3622 return nullptr;
3623}
3624
3625unsigned clang_Cursor_hasAttrs(CXCursor C) {
3626 const Decl *D = getCursorDecl(C);
3627 if (!D) {
3628 return 0;
3629 }
3630
3631 if (D->hasAttrs()) {
3632 return 1;
3633 }
3634
3635 return 0;
3636}
Guy Benyei11169dd2012-12-18 14:30:41 +00003637unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
3638 return CXSaveTranslationUnit_None;
3639}
3640
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003641static CXSaveError clang_saveTranslationUnit_Impl(CXTranslationUnit TU,
3642 const char *FileName,
3643 unsigned options) {
3644 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003645 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3646 setThreadBackgroundPriority();
3647
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003648 bool hadError = cxtu::getASTUnit(TU)->Save(FileName);
3649 return hadError ? CXSaveError_Unknown : CXSaveError_None;
Guy Benyei11169dd2012-12-18 14:30:41 +00003650}
3651
3652int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3653 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003654 LOG_FUNC_SECTION {
3655 *Log << TU << ' ' << FileName;
3656 }
3657
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003658 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003659 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003660 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003661 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003662
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003663 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003664 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3665 if (!CXXUnit->hasSema())
3666 return CXSaveError_InvalidTU;
3667
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003668 CXSaveError result;
3669 auto SaveTranslationUnitImpl = [=, &result]() {
3670 result = clang_saveTranslationUnit_Impl(TU, FileName, options);
3671 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003672
3673 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3674 getenv("LIBCLANG_NOTHREADS")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003675 SaveTranslationUnitImpl();
Guy Benyei11169dd2012-12-18 14:30:41 +00003676
3677 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3678 PrintLibclangResourceUsage(TU);
3679
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003680 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003681 }
3682
3683 // We have an AST that has invalid nodes due to compiler errors.
3684 // Use a crash recovery thread for protection.
3685
3686 llvm::CrashRecoveryContext CRC;
3687
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003688 if (!RunSafely(CRC, SaveTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003689 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3690 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3691 fprintf(stderr, " 'options' : %d,\n", options);
3692 fprintf(stderr, "}\n");
3693
3694 return CXSaveError_Unknown;
3695
3696 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3697 PrintLibclangResourceUsage(TU);
3698 }
3699
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003700 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003701}
3702
3703void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3704 if (CTUnit) {
3705 // If the translation unit has been marked as unsafe to free, just discard
3706 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003707 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3708 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003709 return;
3710
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003711 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003712 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003713 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3714 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003715 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003716 delete CTUnit;
3717 }
3718}
3719
3720unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3721 return CXReparse_None;
3722}
3723
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003724static CXErrorCode
3725clang_reparseTranslationUnit_Impl(CXTranslationUnit TU,
3726 ArrayRef<CXUnsavedFile> unsaved_files,
3727 unsigned options) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003728 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003729 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003730 LOG_BAD_TU(TU);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003731 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003732 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003733
3734 // Reset the associated diagnostics.
3735 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003736 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003737
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003738 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003739 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3740 setThreadBackgroundPriority();
3741
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003742 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003743 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003744
3745 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3746 new std::vector<ASTUnit::RemappedFile>());
3747
Guy Benyei11169dd2012-12-18 14:30:41 +00003748 // Recover resources if we crash before exiting this function.
3749 llvm::CrashRecoveryContextCleanupRegistrar<
3750 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003751
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003752 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003753 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003754 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003755 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003756 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003757
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003758 if (!CXXUnit->Reparse(CXXIdx->getPCHContainerOperations(),
3759 *RemappedFiles.get()))
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003760 return CXError_Success;
3761 if (isASTReadError(CXXUnit))
3762 return CXError_ASTReadError;
3763 return CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003764}
3765
3766int clang_reparseTranslationUnit(CXTranslationUnit TU,
3767 unsigned num_unsaved_files,
3768 struct CXUnsavedFile *unsaved_files,
3769 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003770 LOG_FUNC_SECTION {
3771 *Log << TU;
3772 }
3773
Alp Toker9d85b182014-07-07 01:23:14 +00003774 if (num_unsaved_files && !unsaved_files)
3775 return CXError_InvalidArguments;
3776
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003777 CXErrorCode result;
3778 auto ReparseTranslationUnitImpl = [=, &result]() {
3779 result = clang_reparseTranslationUnit_Impl(
3780 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options);
3781 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003782
3783 if (getenv("LIBCLANG_NOTHREADS")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003784 ReparseTranslationUnitImpl();
Alp Toker5c532982014-07-07 22:42:03 +00003785 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003786 }
3787
3788 llvm::CrashRecoveryContext CRC;
3789
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003790 if (!RunSafely(CRC, ReparseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003791 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003792 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003793 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003794 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3795 PrintLibclangResourceUsage(TU);
3796
Alp Toker5c532982014-07-07 22:42:03 +00003797 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003798}
3799
3800
3801CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003802 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003803 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003804 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003805 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003806
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003807 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003808 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003809}
3810
3811CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003812 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003813 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003814 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003815 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003816
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003817 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003818 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3819}
3820
3821} // end: extern "C"
3822
3823//===----------------------------------------------------------------------===//
3824// CXFile Operations.
3825//===----------------------------------------------------------------------===//
3826
3827extern "C" {
3828CXString clang_getFileName(CXFile SFile) {
3829 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003830 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003831
3832 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003833 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003834}
3835
3836time_t clang_getFileTime(CXFile SFile) {
3837 if (!SFile)
3838 return 0;
3839
3840 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3841 return FEnt->getModificationTime();
3842}
3843
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003844CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003845 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003846 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003847 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003848 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003849
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003850 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003851
3852 FileManager &FMgr = CXXUnit->getFileManager();
3853 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3854}
3855
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003856unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3857 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003858 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003859 LOG_BAD_TU(TU);
3860 return 0;
3861 }
3862
3863 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003864 return 0;
3865
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003866 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003867 FileEntry *FEnt = static_cast<FileEntry *>(file);
3868 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3869 .isFileMultipleIncludeGuarded(FEnt);
3870}
3871
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003872int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3873 if (!file || !outID)
3874 return 1;
3875
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003876 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003877 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3878 outID->data[0] = ID.getDevice();
3879 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003880 outID->data[2] = FEnt->getModificationTime();
3881 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003882}
3883
Argyrios Kyrtzidisac3997e2014-08-16 00:26:19 +00003884int clang_File_isEqual(CXFile file1, CXFile file2) {
3885 if (file1 == file2)
3886 return true;
3887
3888 if (!file1 || !file2)
3889 return false;
3890
3891 FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
3892 FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
3893 return FEnt1->getUniqueID() == FEnt2->getUniqueID();
3894}
3895
Guy Benyei11169dd2012-12-18 14:30:41 +00003896} // end: extern "C"
3897
3898//===----------------------------------------------------------------------===//
3899// CXCursor Operations.
3900//===----------------------------------------------------------------------===//
3901
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003902static const Decl *getDeclFromExpr(const Stmt *E) {
3903 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003904 return getDeclFromExpr(CE->getSubExpr());
3905
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003906 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003907 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003908 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003909 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003910 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003911 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003912 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003913 if (PRE->isExplicitProperty())
3914 return PRE->getExplicitProperty();
3915 // It could be messaging both getter and setter as in:
3916 // ++myobj.myprop;
3917 // in which case prefer to associate the setter since it is less obvious
3918 // from inspecting the source that the setter is going to get called.
3919 if (PRE->isMessagingSetter())
3920 return PRE->getImplicitPropertySetter();
3921 return PRE->getImplicitPropertyGetter();
3922 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003923 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003924 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003925 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003926 if (Expr *Src = OVE->getSourceExpr())
3927 return getDeclFromExpr(Src);
3928
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003929 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003930 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003931 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003932 if (!CE->isElidable())
3933 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003934 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003935 return OME->getMethodDecl();
3936
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003937 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003938 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003939 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003940 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3941 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003942 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003943 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3944 isa<ParmVarDecl>(SizeOfPack->getPack()))
3945 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003946
3947 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003948}
3949
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003950static SourceLocation getLocationFromExpr(const Expr *E) {
3951 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003952 return getLocationFromExpr(CE->getSubExpr());
3953
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003954 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003955 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003956 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003957 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003958 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003959 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003960 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003961 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003962 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003963 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003964 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003965 return PropRef->getLocation();
3966
3967 return E->getLocStart();
3968}
3969
Aaron Ballmana85d3f82015-11-12 15:25:06 +00003970static std::string getMangledStructor(std::unique_ptr<MangleContext> &M,
3971 std::unique_ptr<llvm::DataLayout> &DL,
3972 const NamedDecl *ND,
3973 unsigned StructorType) {
3974 std::string FrontendBuf;
3975 llvm::raw_string_ostream FOS(FrontendBuf);
3976
3977 if (const auto *CD = dyn_cast_or_null<CXXConstructorDecl>(ND))
3978 M->mangleCXXCtor(CD, static_cast<CXXCtorType>(StructorType), FOS);
3979 else if (const auto *DD = dyn_cast_or_null<CXXDestructorDecl>(ND))
3980 M->mangleCXXDtor(DD, static_cast<CXXDtorType>(StructorType), FOS);
3981
3982 std::string BackendBuf;
3983 llvm::raw_string_ostream BOS(BackendBuf);
3984
3985 llvm::Mangler::getNameWithPrefix(BOS, llvm::Twine(FOS.str()), *DL);
3986
3987 return BOS.str();
3988}
3989
Guy Benyei11169dd2012-12-18 14:30:41 +00003990extern "C" {
3991
3992unsigned clang_visitChildren(CXCursor parent,
3993 CXCursorVisitor visitor,
3994 CXClientData client_data) {
3995 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3996 /*VisitPreprocessorLast=*/false);
3997 return CursorVis.VisitChildren(parent);
3998}
3999
4000#ifndef __has_feature
4001#define __has_feature(x) 0
4002#endif
4003#if __has_feature(blocks)
4004typedef enum CXChildVisitResult
4005 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
4006
4007static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
4008 CXClientData client_data) {
4009 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
4010 return block(cursor, parent);
4011}
4012#else
4013// If we are compiled with a compiler that doesn't have native blocks support,
4014// define and call the block manually, so the
4015typedef struct _CXChildVisitResult
4016{
4017 void *isa;
4018 int flags;
4019 int reserved;
4020 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
4021 CXCursor);
4022} *CXCursorVisitorBlock;
4023
4024static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
4025 CXClientData client_data) {
4026 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
4027 return block->invoke(block, cursor, parent);
4028}
4029#endif
4030
4031
4032unsigned clang_visitChildrenWithBlock(CXCursor parent,
4033 CXCursorVisitorBlock block) {
4034 return clang_visitChildren(parent, visitWithBlock, block);
4035}
4036
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004037static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004038 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004039 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004040
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004041 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004042 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004043 if (const ObjCPropertyImplDecl *PropImpl =
4044 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004045 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004046 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004047
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004048 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004049 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004050 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004051
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004052 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004053 }
4054
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004055 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004056 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004057
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004058 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00004059 // No, this isn't the same as the code below. getIdentifier() is non-virtual
4060 // and returns different names. NamedDecl returns the class name and
4061 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004062 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004063
4064 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004065 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004066
4067 SmallString<1024> S;
4068 llvm::raw_svector_ostream os(S);
4069 ND->printName(os);
4070
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004071 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004072}
4073
4074CXString clang_getCursorSpelling(CXCursor C) {
4075 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00004076 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004077
4078 if (clang_isReference(C.kind)) {
4079 switch (C.kind) {
4080 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004081 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004082 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004083 }
4084 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004085 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004086 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004087 }
4088 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004089 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004090 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004091 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004092 }
4093 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004094 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004095 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004096 }
4097 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004098 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004099 assert(Type && "Missing type decl");
4100
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004101 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00004102 getAsString());
4103 }
4104 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004105 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004106 assert(Template && "Missing template decl");
4107
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004108 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004109 }
4110
4111 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004112 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004113 assert(NS && "Missing namespace decl");
4114
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004115 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004116 }
4117
4118 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004119 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004120 assert(Field && "Missing member decl");
4121
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004122 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004123 }
4124
4125 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004126 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004127 assert(Label && "Missing label");
4128
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004129 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004130 }
4131
4132 case CXCursor_OverloadedDeclRef: {
4133 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004134 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
4135 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004136 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004137 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004138 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004139 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004140 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004141 OverloadedTemplateStorage *Ovl
4142 = Storage.get<OverloadedTemplateStorage*>();
4143 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004144 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004145 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004146 }
4147
4148 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004149 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004150 assert(Var && "Missing variable decl");
4151
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004152 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004153 }
4154
4155 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004156 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00004157 }
4158 }
4159
4160 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00004161 const Expr *E = getCursorExpr(C);
4162
4163 if (C.kind == CXCursor_ObjCStringLiteral ||
4164 C.kind == CXCursor_StringLiteral) {
4165 const StringLiteral *SLit;
4166 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
4167 SLit = OSL->getString();
4168 } else {
4169 SLit = cast<StringLiteral>(E);
4170 }
4171 SmallString<256> Buf;
4172 llvm::raw_svector_ostream OS(Buf);
4173 SLit->outputString(OS);
4174 return cxstring::createDup(OS.str());
4175 }
4176
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004177 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004178 if (D)
4179 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004180 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004181 }
4182
4183 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004184 const Stmt *S = getCursorStmt(C);
4185 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004186 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004187
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004188 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004189 }
4190
4191 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004192 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00004193 ->getNameStart());
4194
4195 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004196 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00004197 ->getNameStart());
4198
4199 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004200 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004201
4202 if (clang_isDeclaration(C.kind))
4203 return getDeclSpelling(getCursorDecl(C));
4204
4205 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00004206 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004207 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00004208 }
4209
4210 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00004211 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004212 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00004213 }
4214
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004215 if (C.kind == CXCursor_PackedAttr) {
4216 return cxstring::createRef("packed");
4217 }
4218
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00004219 if (C.kind == CXCursor_VisibilityAttr) {
4220 const VisibilityAttr *AA = cast<VisibilityAttr>(cxcursor::getCursorAttr(C));
4221 switch (AA->getVisibility()) {
4222 case VisibilityAttr::VisibilityType::Default:
4223 return cxstring::createRef("default");
4224 case VisibilityAttr::VisibilityType::Hidden:
4225 return cxstring::createRef("hidden");
4226 case VisibilityAttr::VisibilityType::Protected:
4227 return cxstring::createRef("protected");
4228 }
4229 llvm_unreachable("unknown visibility type");
4230 }
4231
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004232 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004233}
4234
4235CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
4236 unsigned pieceIndex,
4237 unsigned options) {
4238 if (clang_Cursor_isNull(C))
4239 return clang_getNullRange();
4240
4241 ASTContext &Ctx = getCursorContext(C);
4242
4243 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004244 const Stmt *S = getCursorStmt(C);
4245 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004246 if (pieceIndex > 0)
4247 return clang_getNullRange();
4248 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
4249 }
4250
4251 return clang_getNullRange();
4252 }
4253
4254 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004255 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00004256 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
4257 if (pieceIndex >= ME->getNumSelectorLocs())
4258 return clang_getNullRange();
4259 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
4260 }
4261 }
4262
4263 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
4264 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004265 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00004266 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
4267 if (pieceIndex >= MD->getNumSelectorLocs())
4268 return clang_getNullRange();
4269 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
4270 }
4271 }
4272
4273 if (C.kind == CXCursor_ObjCCategoryDecl ||
4274 C.kind == CXCursor_ObjCCategoryImplDecl) {
4275 if (pieceIndex > 0)
4276 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004277 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00004278 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
4279 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004280 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00004281 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
4282 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
4283 }
4284
4285 if (C.kind == CXCursor_ModuleImportDecl) {
4286 if (pieceIndex > 0)
4287 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004288 if (const ImportDecl *ImportD =
4289 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004290 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
4291 if (!Locs.empty())
4292 return cxloc::translateSourceRange(Ctx,
4293 SourceRange(Locs.front(), Locs.back()));
4294 }
4295 return clang_getNullRange();
4296 }
4297
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00004298 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
4299 C.kind == CXCursor_ConversionFunction) {
4300 if (pieceIndex > 0)
4301 return clang_getNullRange();
4302 if (const FunctionDecl *FD =
4303 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
4304 DeclarationNameInfo FunctionName = FD->getNameInfo();
4305 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
4306 }
4307 return clang_getNullRange();
4308 }
4309
Guy Benyei11169dd2012-12-18 14:30:41 +00004310 // FIXME: A CXCursor_InclusionDirective should give the location of the
4311 // filename, but we don't keep track of this.
4312
4313 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
4314 // but we don't keep track of this.
4315
4316 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
4317 // but we don't keep track of this.
4318
4319 // Default handling, give the location of the cursor.
4320
4321 if (pieceIndex > 0)
4322 return clang_getNullRange();
4323
4324 CXSourceLocation CXLoc = clang_getCursorLocation(C);
4325 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
4326 return cxloc::translateSourceRange(Ctx, Loc);
4327}
4328
Eli Bendersky44a206f2014-07-31 18:04:56 +00004329CXString clang_Cursor_getMangling(CXCursor C) {
4330 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
4331 return cxstring::createEmpty();
4332
Eli Bendersky44a206f2014-07-31 18:04:56 +00004333 // Mangling only works for functions and variables.
Eli Bendersky79759592014-08-01 15:01:10 +00004334 const Decl *D = getCursorDecl(C);
Eli Bendersky44a206f2014-07-31 18:04:56 +00004335 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
4336 return cxstring::createEmpty();
4337
Eli Bendersky79759592014-08-01 15:01:10 +00004338 // First apply frontend mangling.
Eli Bendersky44a206f2014-07-31 18:04:56 +00004339 const NamedDecl *ND = cast<NamedDecl>(D);
Eli Bendersky79759592014-08-01 15:01:10 +00004340 ASTContext &Ctx = ND->getASTContext();
4341 std::unique_ptr<MangleContext> MC(Ctx.createMangleContext());
Eli Bendersky44a206f2014-07-31 18:04:56 +00004342
Eli Bendersky79759592014-08-01 15:01:10 +00004343 std::string FrontendBuf;
4344 llvm::raw_string_ostream FrontendBufOS(FrontendBuf);
Ehsan Akhgarif8d44de2015-10-08 00:01:20 +00004345 if (MC->shouldMangleDeclName(ND)) {
4346 MC->mangleName(ND, FrontendBufOS);
4347 } else {
4348 ND->printName(FrontendBufOS);
4349 }
Eli Bendersky44a206f2014-07-31 18:04:56 +00004350
Eli Bendersky79759592014-08-01 15:01:10 +00004351 // Now apply backend mangling.
4352 std::unique_ptr<llvm::DataLayout> DL(
Eric Christopher964a5f32015-08-05 23:48:05 +00004353 new llvm::DataLayout(Ctx.getTargetInfo().getDataLayoutString()));
Eli Bendersky79759592014-08-01 15:01:10 +00004354
4355 std::string FinalBuf;
4356 llvm::raw_string_ostream FinalBufOS(FinalBuf);
Rafael Espindolab633d202015-06-23 13:59:36 +00004357 llvm::Mangler::getNameWithPrefix(FinalBufOS, llvm::Twine(FrontendBufOS.str()),
4358 *DL);
Eli Bendersky79759592014-08-01 15:01:10 +00004359
4360 return cxstring::createDup(FinalBufOS.str());
Eli Bendersky44a206f2014-07-31 18:04:56 +00004361}
4362
Saleem Abdulrasool60034432015-11-12 03:57:22 +00004363CXStringSet *clang_Cursor_getCXXManglings(CXCursor C) {
4364 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
4365 return nullptr;
4366
4367 const Decl *D = getCursorDecl(C);
4368 if (!(isa<CXXRecordDecl>(D) || isa<CXXMethodDecl>(D)))
4369 return nullptr;
4370
4371 const NamedDecl *ND = cast<NamedDecl>(D);
4372
4373 ASTContext &Ctx = ND->getASTContext();
4374 std::unique_ptr<MangleContext> M(Ctx.createMangleContext());
4375 std::unique_ptr<llvm::DataLayout> DL(
4376 new llvm::DataLayout(Ctx.getTargetInfo().getDataLayoutString()));
4377
4378 std::vector<std::string> Manglings;
4379
4380 auto hasDefaultCXXMethodCC = [](ASTContext &C, const CXXMethodDecl *MD) {
4381 auto DefaultCC = C.getDefaultCallingConvention(/*IsVariadic=*/false,
4382 /*IsCSSMethod=*/true);
4383 auto CC = MD->getType()->getAs<FunctionProtoType>()->getCallConv();
4384 return CC == DefaultCC;
4385 };
4386
4387 if (const auto *CD = dyn_cast_or_null<CXXConstructorDecl>(ND)) {
4388 Manglings.emplace_back(getMangledStructor(M, DL, CD, Ctor_Base));
4389
4390 if (Ctx.getTargetInfo().getCXXABI().isItaniumFamily())
4391 if (!CD->getParent()->isAbstract())
4392 Manglings.emplace_back(getMangledStructor(M, DL, CD, Ctor_Complete));
4393
4394 if (Ctx.getTargetInfo().getCXXABI().isMicrosoft())
4395 if (CD->hasAttr<DLLExportAttr>() && CD->isDefaultConstructor())
4396 if (!(hasDefaultCXXMethodCC(Ctx, CD) && CD->getNumParams() == 0))
4397 Manglings.emplace_back(getMangledStructor(M, DL, CD,
4398 Ctor_DefaultClosure));
4399 } else if (const auto *DD = dyn_cast_or_null<CXXDestructorDecl>(ND)) {
4400 Manglings.emplace_back(getMangledStructor(M, DL, DD, Dtor_Base));
4401 if (Ctx.getTargetInfo().getCXXABI().isItaniumFamily()) {
4402 Manglings.emplace_back(getMangledStructor(M, DL, DD, Dtor_Complete));
Saleem Abdulrasoold5af8ae2015-12-10 06:30:23 +00004403 if (DD->isVirtual())
Saleem Abdulrasool60034432015-11-12 03:57:22 +00004404 Manglings.emplace_back(getMangledStructor(M, DL, DD, Dtor_Deleting));
4405 }
4406 }
4407
4408 return cxstring::createSet(Manglings);
4409}
4410
Guy Benyei11169dd2012-12-18 14:30:41 +00004411CXString clang_getCursorDisplayName(CXCursor C) {
4412 if (!clang_isDeclaration(C.kind))
4413 return clang_getCursorSpelling(C);
4414
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004415 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004416 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004417 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004418
4419 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004420 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004421 D = FunTmpl->getTemplatedDecl();
4422
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004423 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004424 SmallString<64> Str;
4425 llvm::raw_svector_ostream OS(Str);
4426 OS << *Function;
4427 if (Function->getPrimaryTemplate())
4428 OS << "<>";
4429 OS << "(";
4430 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
4431 if (I)
4432 OS << ", ";
4433 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
4434 }
4435
4436 if (Function->isVariadic()) {
4437 if (Function->getNumParams())
4438 OS << ", ";
4439 OS << "...";
4440 }
4441 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004442 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004443 }
4444
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004445 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004446 SmallString<64> Str;
4447 llvm::raw_svector_ostream OS(Str);
4448 OS << *ClassTemplate;
4449 OS << "<";
4450 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
4451 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
4452 if (I)
4453 OS << ", ";
4454
4455 NamedDecl *Param = Params->getParam(I);
4456 if (Param->getIdentifier()) {
4457 OS << Param->getIdentifier()->getName();
4458 continue;
4459 }
4460
4461 // There is no parameter name, which makes this tricky. Try to come up
4462 // with something useful that isn't too long.
4463 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
4464 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
4465 else if (NonTypeTemplateParmDecl *NTTP
4466 = dyn_cast<NonTypeTemplateParmDecl>(Param))
4467 OS << NTTP->getType().getAsString(Policy);
4468 else
4469 OS << "template<...> class";
4470 }
4471
4472 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004473 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004474 }
4475
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004476 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00004477 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
4478 // If the type was explicitly written, use that.
4479 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004480 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00004481
Benjamin Kramer9170e912013-02-22 15:46:01 +00004482 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00004483 llvm::raw_svector_ostream OS(Str);
4484 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00004485 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00004486 ClassSpec->getTemplateArgs().data(),
4487 ClassSpec->getTemplateArgs().size(),
4488 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004489 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004490 }
4491
4492 return clang_getCursorSpelling(C);
4493}
4494
4495CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
4496 switch (Kind) {
4497 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004498 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004499 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004500 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004501 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004502 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004503 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004504 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004505 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004506 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004507 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004508 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004509 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004510 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004511 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004512 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004513 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004514 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004515 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004516 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004517 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004518 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004519 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004520 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004521 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004522 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004523 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004524 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004525 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004526 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004527 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004528 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004529 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004530 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004531 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004532 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004533 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004534 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004535 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004536 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00004537 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004538 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004539 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004540 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004541 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004542 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004543 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004544 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004545 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004546 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004547 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004548 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004549 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004550 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004551 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004552 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004553 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004554 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004555 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004556 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004557 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004558 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004559 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004560 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004561 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004562 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004563 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004564 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004565 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004566 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004567 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004568 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004569 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004570 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004571 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004572 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004573 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004574 return cxstring::createRef("ArraySubscriptExpr");
Alexey Bataev1a3320e2015-08-25 14:24:04 +00004575 case CXCursor_OMPArraySectionExpr:
4576 return cxstring::createRef("OMPArraySectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004577 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004578 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004579 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004580 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004581 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004582 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004583 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004584 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004585 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004586 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004587 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004588 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004589 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004590 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004591 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004592 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004593 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004594 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004595 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004596 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004597 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004598 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004599 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004600 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004601 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004602 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004603 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004604 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004605 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004606 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004607 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004608 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004609 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004610 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004611 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004612 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004613 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004614 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004615 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004616 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004617 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004618 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004619 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004620 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004621 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004622 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004623 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004624 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004625 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004626 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00004627 case CXCursor_ObjCSelfExpr:
4628 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004629 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004630 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004631 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004632 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004633 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004634 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004635 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004636 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004637 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004638 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004639 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004640 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004641 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004642 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004643 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004644 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004645 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004646 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004647 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004648 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004649 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004650 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004651 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004652 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004653 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004654 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004655 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004656 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004657 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004658 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004659 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004660 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004661 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004662 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004663 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004664 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004665 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004666 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004667 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004668 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004669 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004670 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004671 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004672 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004673 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004674 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004675 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004676 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004677 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004678 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004679 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004680 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004681 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004682 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004683 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004684 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004685 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004686 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004687 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004688 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004689 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004690 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004691 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004692 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004693 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004694 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004695 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004696 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004697 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004698 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004699 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004700 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004701 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004702 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004703 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004704 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004705 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004706 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004707 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004708 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004709 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004710 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004711 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004712 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004713 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004714 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004715 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004716 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00004717 case CXCursor_SEHLeaveStmt:
4718 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004719 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004720 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004721 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004722 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00004723 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004724 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00004725 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004726 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00004727 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004728 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00004729 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004730 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00004731 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004732 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004733 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004734 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004735 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004736 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004737 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004738 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004739 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004740 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004741 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004742 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004743 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004744 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004745 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004746 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004747 case CXCursor_PackedAttr:
4748 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00004749 case CXCursor_PureAttr:
4750 return cxstring::createRef("attribute(pure)");
4751 case CXCursor_ConstAttr:
4752 return cxstring::createRef("attribute(const)");
4753 case CXCursor_NoDuplicateAttr:
4754 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00004755 case CXCursor_CUDAConstantAttr:
4756 return cxstring::createRef("attribute(constant)");
4757 case CXCursor_CUDADeviceAttr:
4758 return cxstring::createRef("attribute(device)");
4759 case CXCursor_CUDAGlobalAttr:
4760 return cxstring::createRef("attribute(global)");
4761 case CXCursor_CUDAHostAttr:
4762 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00004763 case CXCursor_CUDASharedAttr:
4764 return cxstring::createRef("attribute(shared)");
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00004765 case CXCursor_VisibilityAttr:
4766 return cxstring::createRef("attribute(visibility)");
Saleem Abdulrasool8aa0b802015-12-10 18:45:18 +00004767 case CXCursor_DLLExport:
4768 return cxstring::createRef("attribute(dllexport)");
4769 case CXCursor_DLLImport:
4770 return cxstring::createRef("attribute(dllimport)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004771 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004772 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004773 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004774 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00004775 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004776 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004777 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004778 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004779 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004780 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00004781 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004782 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00004783 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004784 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004785 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004786 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004787 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004788 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004789 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004790 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004791 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004792 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004793 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004794 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004795 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004796 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004797 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004798 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004799 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004800 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004801 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004802 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004803 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004804 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004805 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004806 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004807 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004808 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004809 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004810 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004811 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004812 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004813 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004814 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004815 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004816 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004817 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004818 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004819 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004820 return cxstring::createRef("OMPParallelDirective");
4821 case CXCursor_OMPSimdDirective:
4822 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004823 case CXCursor_OMPForDirective:
4824 return cxstring::createRef("OMPForDirective");
Alexander Musmanf82886e2014-09-18 05:12:34 +00004825 case CXCursor_OMPForSimdDirective:
4826 return cxstring::createRef("OMPForSimdDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004827 case CXCursor_OMPSectionsDirective:
4828 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004829 case CXCursor_OMPSectionDirective:
4830 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004831 case CXCursor_OMPSingleDirective:
4832 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004833 case CXCursor_OMPMasterDirective:
4834 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004835 case CXCursor_OMPCriticalDirective:
4836 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004837 case CXCursor_OMPParallelForDirective:
4838 return cxstring::createRef("OMPParallelForDirective");
Alexander Musmane4e893b2014-09-23 09:33:00 +00004839 case CXCursor_OMPParallelForSimdDirective:
4840 return cxstring::createRef("OMPParallelForSimdDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004841 case CXCursor_OMPParallelSectionsDirective:
4842 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004843 case CXCursor_OMPTaskDirective:
4844 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004845 case CXCursor_OMPTaskyieldDirective:
4846 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004847 case CXCursor_OMPBarrierDirective:
4848 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004849 case CXCursor_OMPTaskwaitDirective:
4850 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00004851 case CXCursor_OMPTaskgroupDirective:
4852 return cxstring::createRef("OMPTaskgroupDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00004853 case CXCursor_OMPFlushDirective:
4854 return cxstring::createRef("OMPFlushDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004855 case CXCursor_OMPOrderedDirective:
4856 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00004857 case CXCursor_OMPAtomicDirective:
4858 return cxstring::createRef("OMPAtomicDirective");
Alexey Bataev0bd520b2014-09-19 08:19:49 +00004859 case CXCursor_OMPTargetDirective:
4860 return cxstring::createRef("OMPTargetDirective");
Michael Wong65f367f2015-07-21 13:44:28 +00004861 case CXCursor_OMPTargetDataDirective:
4862 return cxstring::createRef("OMPTargetDataDirective");
Samuel Antaodf67fc42016-01-19 19:15:56 +00004863 case CXCursor_OMPTargetEnterDataDirective:
4864 return cxstring::createRef("OMPTargetEnterDataDirective");
Samuel Antao72590762016-01-19 20:04:50 +00004865 case CXCursor_OMPTargetExitDataDirective:
4866 return cxstring::createRef("OMPTargetExitDataDirective");
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00004867 case CXCursor_OMPTargetParallelDirective:
4868 return cxstring::createRef("OMPTargetParallelDirective");
Alexey Bataev13314bf2014-10-09 04:18:56 +00004869 case CXCursor_OMPTeamsDirective:
4870 return cxstring::createRef("OMPTeamsDirective");
Alexey Bataev6d4ed052015-07-01 06:57:41 +00004871 case CXCursor_OMPCancellationPointDirective:
4872 return cxstring::createRef("OMPCancellationPointDirective");
Alexey Bataev80909872015-07-02 11:25:17 +00004873 case CXCursor_OMPCancelDirective:
4874 return cxstring::createRef("OMPCancelDirective");
Alexey Bataev49f6e782015-12-01 04:18:41 +00004875 case CXCursor_OMPTaskLoopDirective:
4876 return cxstring::createRef("OMPTaskLoopDirective");
Alexey Bataev0a6ed842015-12-03 09:40:15 +00004877 case CXCursor_OMPTaskLoopSimdDirective:
4878 return cxstring::createRef("OMPTaskLoopSimdDirective");
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00004879 case CXCursor_OMPDistributeDirective:
4880 return cxstring::createRef("OMPDistributeDirective");
Francisco Lopes da Silva975a9f62015-01-21 16:24:11 +00004881 case CXCursor_OverloadCandidate:
4882 return cxstring::createRef("OverloadCandidate");
Sergey Kalinichev8f3b1872015-11-15 13:48:32 +00004883 case CXCursor_TypeAliasTemplateDecl:
4884 return cxstring::createRef("TypeAliasTemplateDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004885 }
4886
4887 llvm_unreachable("Unhandled CXCursorKind");
4888}
4889
4890struct GetCursorData {
4891 SourceLocation TokenBeginLoc;
4892 bool PointsAtMacroArgExpansion;
4893 bool VisitedObjCPropertyImplDecl;
4894 SourceLocation VisitedDeclaratorDeclStartLoc;
4895 CXCursor &BestCursor;
4896
4897 GetCursorData(SourceManager &SM,
4898 SourceLocation tokenBegin, CXCursor &outputCursor)
4899 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4900 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4901 VisitedObjCPropertyImplDecl = false;
4902 }
4903};
4904
4905static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4906 CXCursor parent,
4907 CXClientData client_data) {
4908 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4909 CXCursor *BestCursor = &Data->BestCursor;
4910
4911 // If we point inside a macro argument we should provide info of what the
4912 // token is so use the actual cursor, don't replace it with a macro expansion
4913 // cursor.
4914 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4915 return CXChildVisit_Recurse;
4916
4917 if (clang_isDeclaration(cursor.kind)) {
4918 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004919 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004920 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4921 if (MD->isImplicit())
4922 return CXChildVisit_Break;
4923
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004924 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004925 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4926 // Check that when we have multiple @class references in the same line,
4927 // that later ones do not override the previous ones.
4928 // If we have:
4929 // @class Foo, Bar;
4930 // source ranges for both start at '@', so 'Bar' will end up overriding
4931 // 'Foo' even though the cursor location was at 'Foo'.
4932 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4933 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004934 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004935 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4936 if (PrevID != ID &&
4937 !PrevID->isThisDeclarationADefinition() &&
4938 !ID->isThisDeclarationADefinition())
4939 return CXChildVisit_Break;
4940 }
4941
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004942 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004943 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4944 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4945 // Check that when we have multiple declarators in the same line,
4946 // that later ones do not override the previous ones.
4947 // If we have:
4948 // int Foo, Bar;
4949 // source ranges for both start at 'int', so 'Bar' will end up overriding
4950 // 'Foo' even though the cursor location was at 'Foo'.
4951 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4952 return CXChildVisit_Break;
4953 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4954
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004955 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004956 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4957 (void)PropImp;
4958 // Check that when we have multiple @synthesize in the same line,
4959 // that later ones do not override the previous ones.
4960 // If we have:
4961 // @synthesize Foo, Bar;
4962 // source ranges for both start at '@', so 'Bar' will end up overriding
4963 // 'Foo' even though the cursor location was at 'Foo'.
4964 if (Data->VisitedObjCPropertyImplDecl)
4965 return CXChildVisit_Break;
4966 Data->VisitedObjCPropertyImplDecl = true;
4967 }
4968 }
4969
4970 if (clang_isExpression(cursor.kind) &&
4971 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004972 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004973 // Avoid having the cursor of an expression replace the declaration cursor
4974 // when the expression source range overlaps the declaration range.
4975 // This can happen for C++ constructor expressions whose range generally
4976 // include the variable declaration, e.g.:
4977 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4978 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4979 D->getLocation() == Data->TokenBeginLoc)
4980 return CXChildVisit_Break;
4981 }
4982 }
4983
4984 // If our current best cursor is the construction of a temporary object,
4985 // don't replace that cursor with a type reference, because we want
4986 // clang_getCursor() to point at the constructor.
4987 if (clang_isExpression(BestCursor->kind) &&
4988 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4989 cursor.kind == CXCursor_TypeRef) {
4990 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4991 // as having the actual point on the type reference.
4992 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4993 return CXChildVisit_Recurse;
4994 }
Douglas Gregore9d95f12015-07-07 03:57:35 +00004995
4996 // If we already have an Objective-C superclass reference, don't
4997 // update it further.
4998 if (BestCursor->kind == CXCursor_ObjCSuperClassRef)
4999 return CXChildVisit_Break;
5000
Guy Benyei11169dd2012-12-18 14:30:41 +00005001 *BestCursor = cursor;
5002 return CXChildVisit_Recurse;
5003}
5004
5005CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005006 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005007 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005008 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005009 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005010
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005011 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005012 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5013
5014 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
5015 CXCursor Result = cxcursor::getCursor(TU, SLoc);
5016
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005017 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00005018 CXFile SearchFile;
5019 unsigned SearchLine, SearchColumn;
5020 CXFile ResultFile;
5021 unsigned ResultLine, ResultColumn;
5022 CXString SearchFileName, ResultFileName, KindSpelling, USR;
5023 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
5024 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00005025
5026 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
5027 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005028 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00005029 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00005030 SearchFileName = clang_getFileName(SearchFile);
5031 ResultFileName = clang_getFileName(ResultFile);
5032 KindSpelling = clang_getCursorKindSpelling(Result.kind);
5033 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005034 *Log << llvm::format("(%s:%d:%d) = %s",
5035 clang_getCString(SearchFileName), SearchLine, SearchColumn,
5036 clang_getCString(KindSpelling))
5037 << llvm::format("(%s:%d:%d):%s%s",
5038 clang_getCString(ResultFileName), ResultLine, ResultColumn,
5039 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00005040 clang_disposeString(SearchFileName);
5041 clang_disposeString(ResultFileName);
5042 clang_disposeString(KindSpelling);
5043 clang_disposeString(USR);
5044
5045 CXCursor Definition = clang_getCursorDefinition(Result);
5046 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
5047 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
5048 CXString DefinitionKindSpelling
5049 = clang_getCursorKindSpelling(Definition.kind);
5050 CXFile DefinitionFile;
5051 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005052 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00005053 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00005054 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005055 *Log << llvm::format(" -> %s(%s:%d:%d)",
5056 clang_getCString(DefinitionKindSpelling),
5057 clang_getCString(DefinitionFileName),
5058 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00005059 clang_disposeString(DefinitionFileName);
5060 clang_disposeString(DefinitionKindSpelling);
5061 }
5062 }
5063
5064 return Result;
5065}
5066
5067CXCursor clang_getNullCursor(void) {
5068 return MakeCXCursorInvalid(CXCursor_InvalidFile);
5069}
5070
5071unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005072 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
5073 // can't set consistently. For example, when visiting a DeclStmt we will set
5074 // it but we don't set it on the result of clang_getCursorDefinition for
5075 // a reference of the same declaration.
5076 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
5077 // when visiting a DeclStmt currently, the AST should be enhanced to be able
5078 // to provide that kind of info.
5079 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00005080 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005081 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00005082 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005083
Guy Benyei11169dd2012-12-18 14:30:41 +00005084 return X == Y;
5085}
5086
5087unsigned clang_hashCursor(CXCursor C) {
5088 unsigned Index = 0;
5089 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
5090 Index = 1;
5091
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005092 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00005093 std::make_pair(C.kind, C.data[Index]));
5094}
5095
5096unsigned clang_isInvalid(enum CXCursorKind K) {
5097 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
5098}
5099
5100unsigned clang_isDeclaration(enum CXCursorKind K) {
5101 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
5102 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
5103}
5104
5105unsigned clang_isReference(enum CXCursorKind K) {
5106 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
5107}
5108
5109unsigned clang_isExpression(enum CXCursorKind K) {
5110 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
5111}
5112
5113unsigned clang_isStatement(enum CXCursorKind K) {
5114 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
5115}
5116
5117unsigned clang_isAttribute(enum CXCursorKind K) {
5118 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
5119}
5120
5121unsigned clang_isTranslationUnit(enum CXCursorKind K) {
5122 return K == CXCursor_TranslationUnit;
5123}
5124
5125unsigned clang_isPreprocessing(enum CXCursorKind K) {
5126 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
5127}
5128
5129unsigned clang_isUnexposed(enum CXCursorKind K) {
5130 switch (K) {
5131 case CXCursor_UnexposedDecl:
5132 case CXCursor_UnexposedExpr:
5133 case CXCursor_UnexposedStmt:
5134 case CXCursor_UnexposedAttr:
5135 return true;
5136 default:
5137 return false;
5138 }
5139}
5140
5141CXCursorKind clang_getCursorKind(CXCursor C) {
5142 return C.kind;
5143}
5144
5145CXSourceLocation clang_getCursorLocation(CXCursor C) {
5146 if (clang_isReference(C.kind)) {
5147 switch (C.kind) {
5148 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005149 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00005150 = getCursorObjCSuperClassRef(C);
5151 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5152 }
5153
5154 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005155 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00005156 = getCursorObjCProtocolRef(C);
5157 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5158 }
5159
5160 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005161 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00005162 = getCursorObjCClassRef(C);
5163 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5164 }
5165
5166 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005167 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005168 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5169 }
5170
5171 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005172 std::pair<const TemplateDecl *, SourceLocation> P =
5173 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005174 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5175 }
5176
5177 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005178 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005179 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5180 }
5181
5182 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005183 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005184 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5185 }
5186
5187 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005188 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005189 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5190 }
5191
5192 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005193 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005194 if (!BaseSpec)
5195 return clang_getNullLocation();
5196
5197 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
5198 return cxloc::translateSourceLocation(getCursorContext(C),
5199 TSInfo->getTypeLoc().getBeginLoc());
5200
5201 return cxloc::translateSourceLocation(getCursorContext(C),
5202 BaseSpec->getLocStart());
5203 }
5204
5205 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005206 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005207 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
5208 }
5209
5210 case CXCursor_OverloadedDeclRef:
5211 return cxloc::translateSourceLocation(getCursorContext(C),
5212 getCursorOverloadedDeclRef(C).second);
5213
5214 default:
5215 // FIXME: Need a way to enumerate all non-reference cases.
5216 llvm_unreachable("Missed a reference kind");
5217 }
5218 }
5219
5220 if (clang_isExpression(C.kind))
5221 return cxloc::translateSourceLocation(getCursorContext(C),
5222 getLocationFromExpr(getCursorExpr(C)));
5223
5224 if (clang_isStatement(C.kind))
5225 return cxloc::translateSourceLocation(getCursorContext(C),
5226 getCursorStmt(C)->getLocStart());
5227
5228 if (C.kind == CXCursor_PreprocessingDirective) {
5229 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
5230 return cxloc::translateSourceLocation(getCursorContext(C), L);
5231 }
5232
5233 if (C.kind == CXCursor_MacroExpansion) {
5234 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005235 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00005236 return cxloc::translateSourceLocation(getCursorContext(C), L);
5237 }
5238
5239 if (C.kind == CXCursor_MacroDefinition) {
5240 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
5241 return cxloc::translateSourceLocation(getCursorContext(C), L);
5242 }
5243
5244 if (C.kind == CXCursor_InclusionDirective) {
5245 SourceLocation L
5246 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
5247 return cxloc::translateSourceLocation(getCursorContext(C), L);
5248 }
5249
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00005250 if (clang_isAttribute(C.kind)) {
5251 SourceLocation L
5252 = cxcursor::getCursorAttr(C)->getLocation();
5253 return cxloc::translateSourceLocation(getCursorContext(C), L);
5254 }
5255
Guy Benyei11169dd2012-12-18 14:30:41 +00005256 if (!clang_isDeclaration(C.kind))
5257 return clang_getNullLocation();
5258
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005259 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005260 if (!D)
5261 return clang_getNullLocation();
5262
5263 SourceLocation Loc = D->getLocation();
5264 // FIXME: Multiple variables declared in a single declaration
5265 // currently lack the information needed to correctly determine their
5266 // ranges when accounting for the type-specifier. We use context
5267 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
5268 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005269 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005270 if (!cxcursor::isFirstInDeclGroup(C))
5271 Loc = VD->getLocation();
5272 }
5273
5274 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005275 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005276 Loc = MD->getSelectorStartLoc();
5277
5278 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
5279}
5280
5281} // end extern "C"
5282
5283CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
5284 assert(TU);
5285
5286 // Guard against an invalid SourceLocation, or we may assert in one
5287 // of the following calls.
5288 if (SLoc.isInvalid())
5289 return clang_getNullCursor();
5290
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005291 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005292
5293 // Translate the given source location to make it point at the beginning of
5294 // the token under the cursor.
5295 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
5296 CXXUnit->getASTContext().getLangOpts());
5297
5298 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
5299 if (SLoc.isValid()) {
5300 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
5301 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
5302 /*VisitPreprocessorLast=*/true,
5303 /*VisitIncludedEntities=*/false,
5304 SourceLocation(SLoc));
5305 CursorVis.visitFileRegion();
5306 }
5307
5308 return Result;
5309}
5310
5311static SourceRange getRawCursorExtent(CXCursor C) {
5312 if (clang_isReference(C.kind)) {
5313 switch (C.kind) {
5314 case CXCursor_ObjCSuperClassRef:
5315 return getCursorObjCSuperClassRef(C).second;
5316
5317 case CXCursor_ObjCProtocolRef:
5318 return getCursorObjCProtocolRef(C).second;
5319
5320 case CXCursor_ObjCClassRef:
5321 return getCursorObjCClassRef(C).second;
5322
5323 case CXCursor_TypeRef:
5324 return getCursorTypeRef(C).second;
5325
5326 case CXCursor_TemplateRef:
5327 return getCursorTemplateRef(C).second;
5328
5329 case CXCursor_NamespaceRef:
5330 return getCursorNamespaceRef(C).second;
5331
5332 case CXCursor_MemberRef:
5333 return getCursorMemberRef(C).second;
5334
5335 case CXCursor_CXXBaseSpecifier:
5336 return getCursorCXXBaseSpecifier(C)->getSourceRange();
5337
5338 case CXCursor_LabelRef:
5339 return getCursorLabelRef(C).second;
5340
5341 case CXCursor_OverloadedDeclRef:
5342 return getCursorOverloadedDeclRef(C).second;
5343
5344 case CXCursor_VariableRef:
5345 return getCursorVariableRef(C).second;
5346
5347 default:
5348 // FIXME: Need a way to enumerate all non-reference cases.
5349 llvm_unreachable("Missed a reference kind");
5350 }
5351 }
5352
5353 if (clang_isExpression(C.kind))
5354 return getCursorExpr(C)->getSourceRange();
5355
5356 if (clang_isStatement(C.kind))
5357 return getCursorStmt(C)->getSourceRange();
5358
5359 if (clang_isAttribute(C.kind))
5360 return getCursorAttr(C)->getRange();
5361
5362 if (C.kind == CXCursor_PreprocessingDirective)
5363 return cxcursor::getCursorPreprocessingDirective(C);
5364
5365 if (C.kind == CXCursor_MacroExpansion) {
5366 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005367 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005368 return TU->mapRangeFromPreamble(Range);
5369 }
5370
5371 if (C.kind == CXCursor_MacroDefinition) {
5372 ASTUnit *TU = getCursorASTUnit(C);
5373 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
5374 return TU->mapRangeFromPreamble(Range);
5375 }
5376
5377 if (C.kind == CXCursor_InclusionDirective) {
5378 ASTUnit *TU = getCursorASTUnit(C);
5379 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
5380 return TU->mapRangeFromPreamble(Range);
5381 }
5382
5383 if (C.kind == CXCursor_TranslationUnit) {
5384 ASTUnit *TU = getCursorASTUnit(C);
5385 FileID MainID = TU->getSourceManager().getMainFileID();
5386 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
5387 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
5388 return SourceRange(Start, End);
5389 }
5390
5391 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005392 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005393 if (!D)
5394 return SourceRange();
5395
5396 SourceRange R = D->getSourceRange();
5397 // FIXME: Multiple variables declared in a single declaration
5398 // currently lack the information needed to correctly determine their
5399 // ranges when accounting for the type-specifier. We use context
5400 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
5401 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005402 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005403 if (!cxcursor::isFirstInDeclGroup(C))
5404 R.setBegin(VD->getLocation());
5405 }
5406 return R;
5407 }
5408 return SourceRange();
5409}
5410
5411/// \brief Retrieves the "raw" cursor extent, which is then extended to include
5412/// the decl-specifier-seq for declarations.
5413static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
5414 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005415 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005416 if (!D)
5417 return SourceRange();
5418
5419 SourceRange R = D->getSourceRange();
5420
5421 // Adjust the start of the location for declarations preceded by
5422 // declaration specifiers.
5423 SourceLocation StartLoc;
5424 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
5425 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
5426 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005427 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005428 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
5429 StartLoc = TI->getTypeLoc().getLocStart();
5430 }
5431
5432 if (StartLoc.isValid() && R.getBegin().isValid() &&
5433 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
5434 R.setBegin(StartLoc);
5435
5436 // FIXME: Multiple variables declared in a single declaration
5437 // currently lack the information needed to correctly determine their
5438 // ranges when accounting for the type-specifier. We use context
5439 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
5440 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005441 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005442 if (!cxcursor::isFirstInDeclGroup(C))
5443 R.setBegin(VD->getLocation());
5444 }
5445
5446 return R;
5447 }
5448
5449 return getRawCursorExtent(C);
5450}
5451
5452extern "C" {
5453
5454CXSourceRange clang_getCursorExtent(CXCursor C) {
5455 SourceRange R = getRawCursorExtent(C);
5456 if (R.isInvalid())
5457 return clang_getNullRange();
5458
5459 return cxloc::translateSourceRange(getCursorContext(C), R);
5460}
5461
5462CXCursor clang_getCursorReferenced(CXCursor C) {
5463 if (clang_isInvalid(C.kind))
5464 return clang_getNullCursor();
5465
5466 CXTranslationUnit tu = getCursorTU(C);
5467 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005468 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005469 if (!D)
5470 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005471 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005472 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005473 if (const ObjCPropertyImplDecl *PropImpl =
5474 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005475 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
5476 return MakeCXCursor(Property, tu);
5477
5478 return C;
5479 }
5480
5481 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005482 const Expr *E = getCursorExpr(C);
5483 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00005484 if (D) {
5485 CXCursor declCursor = MakeCXCursor(D, tu);
5486 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
5487 declCursor);
5488 return declCursor;
5489 }
5490
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005491 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00005492 return MakeCursorOverloadedDeclRef(Ovl, tu);
5493
5494 return clang_getNullCursor();
5495 }
5496
5497 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005498 const Stmt *S = getCursorStmt(C);
5499 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00005500 if (LabelDecl *label = Goto->getLabel())
5501 if (LabelStmt *labelS = label->getStmt())
5502 return MakeCXCursor(labelS, getCursorDecl(C), tu);
5503
5504 return clang_getNullCursor();
5505 }
Richard Smith66a81862015-05-04 02:25:31 +00005506
Guy Benyei11169dd2012-12-18 14:30:41 +00005507 if (C.kind == CXCursor_MacroExpansion) {
Richard Smith66a81862015-05-04 02:25:31 +00005508 if (const MacroDefinitionRecord *Def =
5509 getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005510 return MakeMacroDefinitionCursor(Def, tu);
5511 }
5512
5513 if (!clang_isReference(C.kind))
5514 return clang_getNullCursor();
5515
5516 switch (C.kind) {
5517 case CXCursor_ObjCSuperClassRef:
5518 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
5519
5520 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005521 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
5522 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005523 return MakeCXCursor(Def, tu);
5524
5525 return MakeCXCursor(Prot, tu);
5526 }
5527
5528 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005529 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
5530 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005531 return MakeCXCursor(Def, tu);
5532
5533 return MakeCXCursor(Class, tu);
5534 }
5535
5536 case CXCursor_TypeRef:
5537 return MakeCXCursor(getCursorTypeRef(C).first, tu );
5538
5539 case CXCursor_TemplateRef:
5540 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
5541
5542 case CXCursor_NamespaceRef:
5543 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
5544
5545 case CXCursor_MemberRef:
5546 return MakeCXCursor(getCursorMemberRef(C).first, tu );
5547
5548 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005549 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005550 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
5551 tu ));
5552 }
5553
5554 case CXCursor_LabelRef:
5555 // FIXME: We end up faking the "parent" declaration here because we
5556 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005557 return MakeCXCursor(getCursorLabelRef(C).first,
5558 cxtu::getASTUnit(tu)->getASTContext()
5559 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00005560 tu);
5561
5562 case CXCursor_OverloadedDeclRef:
5563 return C;
5564
5565 case CXCursor_VariableRef:
5566 return MakeCXCursor(getCursorVariableRef(C).first, tu);
5567
5568 default:
5569 // We would prefer to enumerate all non-reference cursor kinds here.
5570 llvm_unreachable("Unhandled reference cursor kind");
5571 }
5572}
5573
5574CXCursor clang_getCursorDefinition(CXCursor C) {
5575 if (clang_isInvalid(C.kind))
5576 return clang_getNullCursor();
5577
5578 CXTranslationUnit TU = getCursorTU(C);
5579
5580 bool WasReference = false;
5581 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
5582 C = clang_getCursorReferenced(C);
5583 WasReference = true;
5584 }
5585
5586 if (C.kind == CXCursor_MacroExpansion)
5587 return clang_getCursorReferenced(C);
5588
5589 if (!clang_isDeclaration(C.kind))
5590 return clang_getNullCursor();
5591
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005592 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005593 if (!D)
5594 return clang_getNullCursor();
5595
5596 switch (D->getKind()) {
5597 // Declaration kinds that don't really separate the notions of
5598 // declaration and definition.
5599 case Decl::Namespace:
5600 case Decl::Typedef:
5601 case Decl::TypeAlias:
5602 case Decl::TypeAliasTemplate:
5603 case Decl::TemplateTypeParm:
5604 case Decl::EnumConstant:
5605 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00005606 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005607 case Decl::IndirectField:
5608 case Decl::ObjCIvar:
5609 case Decl::ObjCAtDefsField:
5610 case Decl::ImplicitParam:
5611 case Decl::ParmVar:
5612 case Decl::NonTypeTemplateParm:
5613 case Decl::TemplateTemplateParm:
5614 case Decl::ObjCCategoryImpl:
5615 case Decl::ObjCImplementation:
5616 case Decl::AccessSpec:
5617 case Decl::LinkageSpec:
5618 case Decl::ObjCPropertyImpl:
5619 case Decl::FileScopeAsm:
5620 case Decl::StaticAssert:
5621 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00005622 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00005623 case Decl::Label: // FIXME: Is this right??
5624 case Decl::ClassScopeFunctionSpecialization:
5625 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00005626 case Decl::OMPThreadPrivate:
Douglas Gregor85f3f952015-07-07 03:57:15 +00005627 case Decl::ObjCTypeParam:
David Majnemerd9b1a4f2015-11-04 03:40:30 +00005628 case Decl::BuiltinTemplate:
Guy Benyei11169dd2012-12-18 14:30:41 +00005629 return C;
5630
5631 // Declaration kinds that don't make any sense here, but are
5632 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00005633 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005634 case Decl::TranslationUnit:
Richard Smithf19e1272015-03-07 00:04:49 +00005635 case Decl::ExternCContext:
Guy Benyei11169dd2012-12-18 14:30:41 +00005636 break;
5637
5638 // Declaration kinds for which the definition is not resolvable.
5639 case Decl::UnresolvedUsingTypename:
5640 case Decl::UnresolvedUsingValue:
5641 break;
5642
5643 case Decl::UsingDirective:
5644 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
5645 TU);
5646
5647 case Decl::NamespaceAlias:
5648 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
5649
5650 case Decl::Enum:
5651 case Decl::Record:
5652 case Decl::CXXRecord:
5653 case Decl::ClassTemplateSpecialization:
5654 case Decl::ClassTemplatePartialSpecialization:
5655 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
5656 return MakeCXCursor(Def, TU);
5657 return clang_getNullCursor();
5658
5659 case Decl::Function:
5660 case Decl::CXXMethod:
5661 case Decl::CXXConstructor:
5662 case Decl::CXXDestructor:
5663 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00005664 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005665 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00005666 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005667 return clang_getNullCursor();
5668 }
5669
Larisse Voufo39a1e502013-08-06 01:03:05 +00005670 case Decl::Var:
5671 case Decl::VarTemplateSpecialization:
5672 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00005673 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005674 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005675 return MakeCXCursor(Def, TU);
5676 return clang_getNullCursor();
5677 }
5678
5679 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00005680 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005681 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
5682 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
5683 return clang_getNullCursor();
5684 }
5685
5686 case Decl::ClassTemplate: {
5687 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
5688 ->getDefinition())
5689 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
5690 TU);
5691 return clang_getNullCursor();
5692 }
5693
Larisse Voufo39a1e502013-08-06 01:03:05 +00005694 case Decl::VarTemplate: {
5695 if (VarDecl *Def =
5696 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
5697 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
5698 return clang_getNullCursor();
5699 }
5700
Guy Benyei11169dd2012-12-18 14:30:41 +00005701 case Decl::Using:
5702 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
5703 D->getLocation(), TU);
5704
5705 case Decl::UsingShadow:
5706 return clang_getCursorDefinition(
5707 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
5708 TU));
5709
5710 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005711 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005712 if (Method->isThisDeclarationADefinition())
5713 return C;
5714
5715 // Dig out the method definition in the associated
5716 // @implementation, if we have it.
5717 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005718 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005719 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
5720 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
5721 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
5722 Method->isInstanceMethod()))
5723 if (Def->isThisDeclarationADefinition())
5724 return MakeCXCursor(Def, TU);
5725
5726 return clang_getNullCursor();
5727 }
5728
5729 case Decl::ObjCCategory:
5730 if (ObjCCategoryImplDecl *Impl
5731 = cast<ObjCCategoryDecl>(D)->getImplementation())
5732 return MakeCXCursor(Impl, TU);
5733 return clang_getNullCursor();
5734
5735 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005736 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005737 return MakeCXCursor(Def, TU);
5738 return clang_getNullCursor();
5739
5740 case Decl::ObjCInterface: {
5741 // There are two notions of a "definition" for an Objective-C
5742 // class: the interface and its implementation. When we resolved a
5743 // reference to an Objective-C class, produce the @interface as
5744 // the definition; when we were provided with the interface,
5745 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005746 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005747 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005748 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005749 return MakeCXCursor(Def, TU);
5750 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
5751 return MakeCXCursor(Impl, TU);
5752 return clang_getNullCursor();
5753 }
5754
5755 case Decl::ObjCProperty:
5756 // FIXME: We don't really know where to find the
5757 // ObjCPropertyImplDecls that implement this property.
5758 return clang_getNullCursor();
5759
5760 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005761 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005762 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005763 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005764 return MakeCXCursor(Def, TU);
5765
5766 return clang_getNullCursor();
5767
5768 case Decl::Friend:
5769 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
5770 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5771 return clang_getNullCursor();
5772
5773 case Decl::FriendTemplate:
5774 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
5775 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5776 return clang_getNullCursor();
5777 }
5778
5779 return clang_getNullCursor();
5780}
5781
5782unsigned clang_isCursorDefinition(CXCursor C) {
5783 if (!clang_isDeclaration(C.kind))
5784 return 0;
5785
5786 return clang_getCursorDefinition(C) == C;
5787}
5788
5789CXCursor clang_getCanonicalCursor(CXCursor C) {
5790 if (!clang_isDeclaration(C.kind))
5791 return C;
5792
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005793 if (const Decl *D = getCursorDecl(C)) {
5794 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005795 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5796 return MakeCXCursor(CatD, getCursorTU(C));
5797
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005798 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5799 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00005800 return MakeCXCursor(IFD, getCursorTU(C));
5801
5802 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5803 }
5804
5805 return C;
5806}
5807
5808int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5809 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5810}
5811
5812unsigned clang_getNumOverloadedDecls(CXCursor C) {
5813 if (C.kind != CXCursor_OverloadedDeclRef)
5814 return 0;
5815
5816 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005817 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005818 return E->getNumDecls();
5819
5820 if (OverloadedTemplateStorage *S
5821 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5822 return S->size();
5823
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005824 const Decl *D = Storage.get<const Decl *>();
5825 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005826 return Using->shadow_size();
5827
5828 return 0;
5829}
5830
5831CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5832 if (cursor.kind != CXCursor_OverloadedDeclRef)
5833 return clang_getNullCursor();
5834
5835 if (index >= clang_getNumOverloadedDecls(cursor))
5836 return clang_getNullCursor();
5837
5838 CXTranslationUnit TU = getCursorTU(cursor);
5839 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005840 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005841 return MakeCXCursor(E->decls_begin()[index], TU);
5842
5843 if (OverloadedTemplateStorage *S
5844 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5845 return MakeCXCursor(S->begin()[index], TU);
5846
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005847 const Decl *D = Storage.get<const Decl *>();
5848 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005849 // FIXME: This is, unfortunately, linear time.
5850 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5851 std::advance(Pos, index);
5852 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5853 }
5854
5855 return clang_getNullCursor();
5856}
5857
5858void clang_getDefinitionSpellingAndExtent(CXCursor C,
5859 const char **startBuf,
5860 const char **endBuf,
5861 unsigned *startLine,
5862 unsigned *startColumn,
5863 unsigned *endLine,
5864 unsigned *endColumn) {
5865 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005866 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005867 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5868
5869 SourceManager &SM = FD->getASTContext().getSourceManager();
5870 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5871 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5872 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5873 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5874 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5875 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5876}
5877
5878
5879CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5880 unsigned PieceIndex) {
5881 RefNamePieces Pieces;
5882
5883 switch (C.kind) {
5884 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005885 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005886 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5887 E->getQualifierLoc().getSourceRange());
5888 break;
5889
5890 case CXCursor_DeclRefExpr:
James Y Knight04ec5bf2015-12-24 02:59:37 +00005891 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C))) {
5892 SourceRange TemplateArgLoc(E->getLAngleLoc(), E->getRAngleLoc());
5893 Pieces =
5894 buildPieces(NameFlags, false, E->getNameInfo(),
5895 E->getQualifierLoc().getSourceRange(), &TemplateArgLoc);
5896 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005897 break;
5898
5899 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005900 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005901 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005902 const Expr *Callee = OCE->getCallee();
5903 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005904 Callee = ICE->getSubExpr();
5905
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005906 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005907 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5908 DRE->getQualifierLoc().getSourceRange());
5909 }
5910 break;
5911
5912 default:
5913 break;
5914 }
5915
5916 if (Pieces.empty()) {
5917 if (PieceIndex == 0)
5918 return clang_getCursorExtent(C);
5919 } else if (PieceIndex < Pieces.size()) {
5920 SourceRange R = Pieces[PieceIndex];
5921 if (R.isValid())
5922 return cxloc::translateSourceRange(getCursorContext(C), R);
5923 }
5924
5925 return clang_getNullRange();
5926}
5927
5928void clang_enableStackTraces(void) {
5929 llvm::sys::PrintStackTraceOnErrorSignal();
5930}
5931
5932void clang_executeOnThread(void (*fn)(void*), void *user_data,
5933 unsigned stack_size) {
5934 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5935}
5936
5937} // end: extern "C"
5938
5939//===----------------------------------------------------------------------===//
5940// Token-based Operations.
5941//===----------------------------------------------------------------------===//
5942
5943/* CXToken layout:
5944 * int_data[0]: a CXTokenKind
5945 * int_data[1]: starting token location
5946 * int_data[2]: token length
5947 * int_data[3]: reserved
5948 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5949 * otherwise unused.
5950 */
5951extern "C" {
5952
5953CXTokenKind clang_getTokenKind(CXToken CXTok) {
5954 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5955}
5956
5957CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5958 switch (clang_getTokenKind(CXTok)) {
5959 case CXToken_Identifier:
5960 case CXToken_Keyword:
5961 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005962 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005963 ->getNameStart());
5964
5965 case CXToken_Literal: {
5966 // We have stashed the starting pointer in the ptr_data field. Use it.
5967 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005968 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005969 }
5970
5971 case CXToken_Punctuation:
5972 case CXToken_Comment:
5973 break;
5974 }
5975
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005976 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005977 LOG_BAD_TU(TU);
5978 return cxstring::createEmpty();
5979 }
5980
Guy Benyei11169dd2012-12-18 14:30:41 +00005981 // We have to find the starting buffer pointer the hard way, by
5982 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005983 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005984 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005985 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005986
5987 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5988 std::pair<FileID, unsigned> LocInfo
5989 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5990 bool Invalid = false;
5991 StringRef Buffer
5992 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5993 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005994 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005995
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005996 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005997}
5998
5999CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006000 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006001 LOG_BAD_TU(TU);
6002 return clang_getNullLocation();
6003 }
6004
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006005 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006006 if (!CXXUnit)
6007 return clang_getNullLocation();
6008
6009 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
6010 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
6011}
6012
6013CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006014 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006015 LOG_BAD_TU(TU);
6016 return clang_getNullRange();
6017 }
6018
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006019 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006020 if (!CXXUnit)
6021 return clang_getNullRange();
6022
6023 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
6024 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
6025}
6026
6027static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
6028 SmallVectorImpl<CXToken> &CXTokens) {
6029 SourceManager &SourceMgr = CXXUnit->getSourceManager();
6030 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006031 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00006032 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006033 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00006034
6035 // Cannot tokenize across files.
6036 if (BeginLocInfo.first != EndLocInfo.first)
6037 return;
6038
6039 // Create a lexer
6040 bool Invalid = false;
6041 StringRef Buffer
6042 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
6043 if (Invalid)
6044 return;
6045
6046 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
6047 CXXUnit->getASTContext().getLangOpts(),
6048 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
6049 Lex.SetCommentRetentionState(true);
6050
6051 // Lex tokens until we hit the end of the range.
6052 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
6053 Token Tok;
6054 bool previousWasAt = false;
6055 do {
6056 // Lex the next token
6057 Lex.LexFromRawLexer(Tok);
6058 if (Tok.is(tok::eof))
6059 break;
6060
6061 // Initialize the CXToken.
6062 CXToken CXTok;
6063
6064 // - Common fields
6065 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
6066 CXTok.int_data[2] = Tok.getLength();
6067 CXTok.int_data[3] = 0;
6068
6069 // - Kind-specific fields
6070 if (Tok.isLiteral()) {
6071 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006072 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00006073 } else if (Tok.is(tok::raw_identifier)) {
6074 // Lookup the identifier to determine whether we have a keyword.
6075 IdentifierInfo *II
6076 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
6077
6078 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
6079 CXTok.int_data[0] = CXToken_Keyword;
6080 }
6081 else {
6082 CXTok.int_data[0] = Tok.is(tok::identifier)
6083 ? CXToken_Identifier
6084 : CXToken_Keyword;
6085 }
6086 CXTok.ptr_data = II;
6087 } else if (Tok.is(tok::comment)) {
6088 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00006089 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006090 } else {
6091 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00006092 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006093 }
6094 CXTokens.push_back(CXTok);
6095 previousWasAt = Tok.is(tok::at);
6096 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
6097}
6098
6099void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
6100 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006101 LOG_FUNC_SECTION {
6102 *Log << TU << ' ' << Range;
6103 }
6104
Guy Benyei11169dd2012-12-18 14:30:41 +00006105 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00006106 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006107 if (NumTokens)
6108 *NumTokens = 0;
6109
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006110 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006111 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00006112 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006113 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00006114
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006115 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006116 if (!CXXUnit || !Tokens || !NumTokens)
6117 return;
6118
6119 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
6120
6121 SourceRange R = cxloc::translateCXSourceRange(Range);
6122 if (R.isInvalid())
6123 return;
6124
6125 SmallVector<CXToken, 32> CXTokens;
6126 getTokens(CXXUnit, R, CXTokens);
6127
6128 if (CXTokens.empty())
6129 return;
6130
6131 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
6132 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
6133 *NumTokens = CXTokens.size();
6134}
6135
6136void clang_disposeTokens(CXTranslationUnit TU,
6137 CXToken *Tokens, unsigned NumTokens) {
6138 free(Tokens);
6139}
6140
6141} // end: extern "C"
6142
6143//===----------------------------------------------------------------------===//
6144// Token annotation APIs.
6145//===----------------------------------------------------------------------===//
6146
Guy Benyei11169dd2012-12-18 14:30:41 +00006147static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
6148 CXCursor parent,
6149 CXClientData client_data);
6150static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
6151 CXClientData client_data);
6152
6153namespace {
6154class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00006155 CXToken *Tokens;
6156 CXCursor *Cursors;
6157 unsigned NumTokens;
6158 unsigned TokIdx;
6159 unsigned PreprocessingTokIdx;
6160 CursorVisitor AnnotateVis;
6161 SourceManager &SrcMgr;
6162 bool HasContextSensitiveKeywords;
6163
6164 struct PostChildrenInfo {
6165 CXCursor Cursor;
6166 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006167 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006168 unsigned BeforeChildrenTokenIdx;
6169 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00006170 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006171
6172 CXToken &getTok(unsigned Idx) {
6173 assert(Idx < NumTokens);
6174 return Tokens[Idx];
6175 }
6176 const CXToken &getTok(unsigned Idx) const {
6177 assert(Idx < NumTokens);
6178 return Tokens[Idx];
6179 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006180 bool MoreTokens() const { return TokIdx < NumTokens; }
6181 unsigned NextToken() const { return TokIdx; }
6182 void AdvanceToken() { ++TokIdx; }
6183 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006184 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006185 }
6186 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006187 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006188 }
6189 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006190 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006191 }
6192
6193 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006194 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00006195 SourceRange);
6196
6197public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006198 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006199 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006200 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00006201 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006202 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00006203 AnnotateTokensVisitor, this,
6204 /*VisitPreprocessorLast=*/true,
6205 /*VisitIncludedEntities=*/false,
6206 RegionOfInterest,
6207 /*VisitDeclsOnly=*/false,
6208 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006209 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00006210 HasContextSensitiveKeywords(false) { }
6211
6212 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
6213 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
6214 bool postVisitChildren(CXCursor cursor);
6215 void AnnotateTokens();
6216
6217 /// \brief Determine whether the annotator saw any cursors that have
6218 /// context-sensitive keywords.
6219 bool hasContextSensitiveKeywords() const {
6220 return HasContextSensitiveKeywords;
6221 }
6222
6223 ~AnnotateTokensWorker() {
6224 assert(PostChildrenInfos.empty());
6225 }
6226};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00006227}
Guy Benyei11169dd2012-12-18 14:30:41 +00006228
6229void AnnotateTokensWorker::AnnotateTokens() {
6230 // Walk the AST within the region of interest, annotating tokens
6231 // along the way.
6232 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006233}
Guy Benyei11169dd2012-12-18 14:30:41 +00006234
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006235static inline void updateCursorAnnotation(CXCursor &Cursor,
6236 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006237 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00006238 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006239 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00006240}
6241
6242/// \brief It annotates and advances tokens with a cursor until the comparison
6243//// between the cursor location and the source range is the same as
6244/// \arg compResult.
6245///
6246/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
6247/// Pass RangeOverlap to annotate tokens inside a range.
6248void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
6249 RangeComparisonResult compResult,
6250 SourceRange range) {
6251 while (MoreTokens()) {
6252 const unsigned I = NextToken();
6253 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006254 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
6255 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00006256
6257 SourceLocation TokLoc = GetTokenLoc(I);
6258 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006259 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00006260 AdvanceToken();
6261 continue;
6262 }
6263 break;
6264 }
6265}
6266
6267/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006268/// \returns true if it advanced beyond all macro tokens, false otherwise.
6269bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00006270 CXCursor updateC,
6271 RangeComparisonResult compResult,
6272 SourceRange range) {
6273 assert(MoreTokens());
6274 assert(isFunctionMacroToken(NextToken()) &&
6275 "Should be called only for macro arg tokens");
6276
6277 // This works differently than annotateAndAdvanceTokens; because expanded
6278 // macro arguments can have arbitrary translation-unit source order, we do not
6279 // advance the token index one by one until a token fails the range test.
6280 // We only advance once past all of the macro arg tokens if all of them
6281 // pass the range test. If one of them fails we keep the token index pointing
6282 // at the start of the macro arg tokens so that the failing token will be
6283 // annotated by a subsequent annotation try.
6284
6285 bool atLeastOneCompFail = false;
6286
6287 unsigned I = NextToken();
6288 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
6289 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
6290 if (TokLoc.isFileID())
6291 continue; // not macro arg token, it's parens or comma.
6292 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
6293 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
6294 Cursors[I] = updateC;
6295 } else
6296 atLeastOneCompFail = true;
6297 }
6298
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006299 if (atLeastOneCompFail)
6300 return false;
6301
6302 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
6303 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00006304}
6305
6306enum CXChildVisitResult
6307AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006308 SourceRange cursorRange = getRawCursorExtent(cursor);
6309 if (cursorRange.isInvalid())
6310 return CXChildVisit_Recurse;
6311
6312 if (!HasContextSensitiveKeywords) {
6313 // Objective-C properties can have context-sensitive keywords.
6314 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006315 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006316 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
6317 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
6318 }
6319 // Objective-C methods can have context-sensitive keywords.
6320 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
6321 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006322 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00006323 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
6324 if (Method->getObjCDeclQualifier())
6325 HasContextSensitiveKeywords = true;
6326 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00006327 for (const auto *P : Method->params()) {
6328 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006329 HasContextSensitiveKeywords = true;
6330 break;
6331 }
6332 }
6333 }
6334 }
6335 }
6336 // C++ methods can have context-sensitive keywords.
6337 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006338 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00006339 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
6340 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
6341 HasContextSensitiveKeywords = true;
6342 }
6343 }
6344 // C++ classes can have context-sensitive keywords.
6345 else if (cursor.kind == CXCursor_StructDecl ||
6346 cursor.kind == CXCursor_ClassDecl ||
6347 cursor.kind == CXCursor_ClassTemplate ||
6348 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006349 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006350 if (D->hasAttr<FinalAttr>())
6351 HasContextSensitiveKeywords = true;
6352 }
6353 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00006354
6355 // Don't override a property annotation with its getter/setter method.
6356 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
6357 parent.kind == CXCursor_ObjCPropertyDecl)
6358 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00006359
6360 if (clang_isPreprocessing(cursor.kind)) {
6361 // Items in the preprocessing record are kept separate from items in
6362 // declarations, so we keep a separate token index.
6363 unsigned SavedTokIdx = TokIdx;
6364 TokIdx = PreprocessingTokIdx;
6365
6366 // Skip tokens up until we catch up to the beginning of the preprocessing
6367 // entry.
6368 while (MoreTokens()) {
6369 const unsigned I = NextToken();
6370 SourceLocation TokLoc = GetTokenLoc(I);
6371 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
6372 case RangeBefore:
6373 AdvanceToken();
6374 continue;
6375 case RangeAfter:
6376 case RangeOverlap:
6377 break;
6378 }
6379 break;
6380 }
6381
6382 // Look at all of the tokens within this range.
6383 while (MoreTokens()) {
6384 const unsigned I = NextToken();
6385 SourceLocation TokLoc = GetTokenLoc(I);
6386 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
6387 case RangeBefore:
6388 llvm_unreachable("Infeasible");
6389 case RangeAfter:
6390 break;
6391 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006392 // For macro expansions, just note where the beginning of the macro
6393 // expansion occurs.
6394 if (cursor.kind == CXCursor_MacroExpansion) {
6395 if (TokLoc == cursorRange.getBegin())
6396 Cursors[I] = cursor;
6397 AdvanceToken();
6398 break;
6399 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006400 // We may have already annotated macro names inside macro definitions.
6401 if (Cursors[I].kind != CXCursor_MacroExpansion)
6402 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00006403 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00006404 continue;
6405 }
6406 break;
6407 }
6408
6409 // Save the preprocessing token index; restore the non-preprocessing
6410 // token index.
6411 PreprocessingTokIdx = TokIdx;
6412 TokIdx = SavedTokIdx;
6413 return CXChildVisit_Recurse;
6414 }
6415
6416 if (cursorRange.isInvalid())
6417 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006418
6419 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00006420 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006421 const enum CXCursorKind K = clang_getCursorKind(parent);
6422 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006423 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
6424 // Attributes are annotated out-of-order, skip tokens until we reach it.
6425 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00006426 ? clang_getNullCursor() : parent;
6427
6428 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
6429
6430 // Avoid having the cursor of an expression "overwrite" the annotation of the
6431 // variable declaration that it belongs to.
6432 // This can happen for C++ constructor expressions whose range generally
6433 // include the variable declaration, e.g.:
6434 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006435 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00006436 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00006437 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006438 const unsigned I = NextToken();
6439 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
6440 E->getLocStart() == D->getLocation() &&
6441 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006442 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00006443 AdvanceToken();
6444 }
6445 }
6446 }
6447
6448 // Before recursing into the children keep some state that we are going
6449 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
6450 // extra work after the child nodes are visited.
6451 // Note that we don't call VisitChildren here to avoid traversing statements
6452 // code-recursively which can blow the stack.
6453
6454 PostChildrenInfo Info;
6455 Info.Cursor = cursor;
6456 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006457 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006458 Info.BeforeChildrenTokenIdx = NextToken();
6459 PostChildrenInfos.push_back(Info);
6460
6461 return CXChildVisit_Recurse;
6462}
6463
6464bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
6465 if (PostChildrenInfos.empty())
6466 return false;
6467 const PostChildrenInfo &Info = PostChildrenInfos.back();
6468 if (!clang_equalCursors(Info.Cursor, cursor))
6469 return false;
6470
6471 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
6472 const unsigned AfterChildren = NextToken();
6473 SourceRange cursorRange = Info.CursorRange;
6474
6475 // Scan the tokens that are at the end of the cursor, but are not captured
6476 // but the child cursors.
6477 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
6478
6479 // Scan the tokens that are at the beginning of the cursor, but are not
6480 // capture by the child cursors.
6481 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
6482 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
6483 break;
6484
6485 Cursors[I] = cursor;
6486 }
6487
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006488 // Attributes are annotated out-of-order, rewind TokIdx to when we first
6489 // encountered the attribute cursor.
6490 if (clang_isAttribute(cursor.kind))
6491 TokIdx = Info.BeforeReachingCursorIdx;
6492
Guy Benyei11169dd2012-12-18 14:30:41 +00006493 PostChildrenInfos.pop_back();
6494 return false;
6495}
6496
6497static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
6498 CXCursor parent,
6499 CXClientData client_data) {
6500 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
6501}
6502
6503static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
6504 CXClientData client_data) {
6505 return static_cast<AnnotateTokensWorker*>(client_data)->
6506 postVisitChildren(cursor);
6507}
6508
6509namespace {
6510
6511/// \brief Uses the macro expansions in the preprocessing record to find
6512/// and mark tokens that are macro arguments. This info is used by the
6513/// AnnotateTokensWorker.
6514class MarkMacroArgTokensVisitor {
6515 SourceManager &SM;
6516 CXToken *Tokens;
6517 unsigned NumTokens;
6518 unsigned CurIdx;
6519
6520public:
6521 MarkMacroArgTokensVisitor(SourceManager &SM,
6522 CXToken *tokens, unsigned numTokens)
6523 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
6524
6525 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
6526 if (cursor.kind != CXCursor_MacroExpansion)
6527 return CXChildVisit_Continue;
6528
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006529 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00006530 if (macroRange.getBegin() == macroRange.getEnd())
6531 return CXChildVisit_Continue; // it's not a function macro.
6532
6533 for (; CurIdx < NumTokens; ++CurIdx) {
6534 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
6535 macroRange.getBegin()))
6536 break;
6537 }
6538
6539 if (CurIdx == NumTokens)
6540 return CXChildVisit_Break;
6541
6542 for (; CurIdx < NumTokens; ++CurIdx) {
6543 SourceLocation tokLoc = getTokenLoc(CurIdx);
6544 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
6545 break;
6546
6547 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
6548 }
6549
6550 if (CurIdx == NumTokens)
6551 return CXChildVisit_Break;
6552
6553 return CXChildVisit_Continue;
6554 }
6555
6556private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006557 CXToken &getTok(unsigned Idx) {
6558 assert(Idx < NumTokens);
6559 return Tokens[Idx];
6560 }
6561 const CXToken &getTok(unsigned Idx) const {
6562 assert(Idx < NumTokens);
6563 return Tokens[Idx];
6564 }
6565
Guy Benyei11169dd2012-12-18 14:30:41 +00006566 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006567 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006568 }
6569
6570 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
6571 // The third field is reserved and currently not used. Use it here
6572 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006573 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00006574 }
6575};
6576
6577} // end anonymous namespace
6578
6579static CXChildVisitResult
6580MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
6581 CXClientData client_data) {
6582 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
6583 parent);
6584}
6585
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006586/// \brief Used by \c annotatePreprocessorTokens.
6587/// \returns true if lexing was finished, false otherwise.
6588static bool lexNext(Lexer &Lex, Token &Tok,
6589 unsigned &NextIdx, unsigned NumTokens) {
6590 if (NextIdx >= NumTokens)
6591 return true;
6592
6593 ++NextIdx;
6594 Lex.LexFromRawLexer(Tok);
Alexander Kornienko1a9f1842015-12-28 15:24:08 +00006595 return Tok.is(tok::eof);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006596}
6597
Guy Benyei11169dd2012-12-18 14:30:41 +00006598static void annotatePreprocessorTokens(CXTranslationUnit TU,
6599 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006600 CXCursor *Cursors,
6601 CXToken *Tokens,
6602 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006603 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006604
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006605 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00006606 SourceManager &SourceMgr = CXXUnit->getSourceManager();
6607 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006608 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00006609 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006610 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00006611
6612 if (BeginLocInfo.first != EndLocInfo.first)
6613 return;
6614
6615 StringRef Buffer;
6616 bool Invalid = false;
6617 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
6618 if (Buffer.empty() || Invalid)
6619 return;
6620
6621 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
6622 CXXUnit->getASTContext().getLangOpts(),
6623 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
6624 Buffer.end());
6625 Lex.SetCommentRetentionState(true);
6626
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006627 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006628 // Lex tokens in raw mode until we hit the end of the range, to avoid
6629 // entering #includes or expanding macros.
6630 while (true) {
6631 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006632 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6633 break;
6634 unsigned TokIdx = NextIdx-1;
6635 assert(Tok.getLocation() ==
6636 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006637
6638 reprocess:
6639 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006640 // We have found a preprocessing directive. Annotate the tokens
6641 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00006642 //
6643 // FIXME: Some simple tests here could identify macro definitions and
6644 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006645
6646 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006647 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6648 break;
6649
Craig Topper69186e72014-06-08 08:38:04 +00006650 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00006651 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006652 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6653 break;
6654
6655 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00006656 IdentifierInfo &II =
6657 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006658 SourceLocation MappedTokLoc =
6659 CXXUnit->mapLocationToPreamble(Tok.getLocation());
6660 MI = getMacroInfo(II, MappedTokLoc, TU);
6661 }
6662 }
6663
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006664 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00006665 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006666 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
6667 finished = true;
6668 break;
6669 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006670 // If we are in a macro definition, check if the token was ever a
6671 // macro name and annotate it if that's the case.
6672 if (MI) {
6673 SourceLocation SaveLoc = Tok.getLocation();
6674 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
Richard Smith66a81862015-05-04 02:25:31 +00006675 MacroDefinitionRecord *MacroDef =
6676 checkForMacroInMacroDefinition(MI, Tok, TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006677 Tok.setLocation(SaveLoc);
6678 if (MacroDef)
Richard Smith66a81862015-05-04 02:25:31 +00006679 Cursors[NextIdx - 1] =
6680 MakeMacroExpansionCursor(MacroDef, Tok.getLocation(), TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006681 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006682 } while (!Tok.isAtStartOfLine());
6683
6684 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
6685 assert(TokIdx <= LastIdx);
6686 SourceLocation EndLoc =
6687 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
6688 CXCursor Cursor =
6689 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
6690
6691 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006692 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006693
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006694 if (finished)
6695 break;
6696 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00006697 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006698 }
6699}
6700
6701// This gets run a separate thread to avoid stack blowout.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006702static void clang_annotateTokensImpl(CXTranslationUnit TU, ASTUnit *CXXUnit,
6703 CXToken *Tokens, unsigned NumTokens,
6704 CXCursor *Cursors) {
Dmitri Gribenko183436e2013-01-26 21:49:50 +00006705 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006706 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
6707 setThreadBackgroundPriority();
6708
6709 // Determine the region of interest, which contains all of the tokens.
6710 SourceRange RegionOfInterest;
6711 RegionOfInterest.setBegin(
6712 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
6713 RegionOfInterest.setEnd(
6714 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
6715 Tokens[NumTokens-1])));
6716
Guy Benyei11169dd2012-12-18 14:30:41 +00006717 // Relex the tokens within the source range to look for preprocessing
6718 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006719 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006720
6721 // If begin location points inside a macro argument, set it to the expansion
6722 // location so we can have the full context when annotating semantically.
6723 {
6724 SourceManager &SM = CXXUnit->getSourceManager();
6725 SourceLocation Loc =
6726 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
6727 if (Loc.isMacroID())
6728 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
6729 }
6730
Guy Benyei11169dd2012-12-18 14:30:41 +00006731 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
6732 // Search and mark tokens that are macro argument expansions.
6733 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
6734 Tokens, NumTokens);
6735 CursorVisitor MacroArgMarker(TU,
6736 MarkMacroArgTokensVisitorDelegate, &Visitor,
6737 /*VisitPreprocessorLast=*/true,
6738 /*VisitIncludedEntities=*/false,
6739 RegionOfInterest);
6740 MacroArgMarker.visitPreprocessedEntitiesInRegion();
6741 }
6742
6743 // Annotate all of the source locations in the region of interest that map to
6744 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006745 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00006746
6747 // FIXME: We use a ridiculous stack size here because the data-recursion
6748 // algorithm uses a large stack frame than the non-data recursive version,
6749 // and AnnotationTokensWorker currently transforms the data-recursion
6750 // algorithm back into a traditional recursion by explicitly calling
6751 // VisitChildren(). We will need to remove this explicit recursive call.
6752 W.AnnotateTokens();
6753
6754 // If we ran into any entities that involve context-sensitive keywords,
6755 // take another pass through the tokens to mark them as such.
6756 if (W.hasContextSensitiveKeywords()) {
6757 for (unsigned I = 0; I != NumTokens; ++I) {
6758 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
6759 continue;
6760
6761 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
6762 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006763 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006764 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
6765 if (Property->getPropertyAttributesAsWritten() != 0 &&
6766 llvm::StringSwitch<bool>(II->getName())
6767 .Case("readonly", true)
6768 .Case("assign", true)
6769 .Case("unsafe_unretained", true)
6770 .Case("readwrite", true)
6771 .Case("retain", true)
6772 .Case("copy", true)
6773 .Case("nonatomic", true)
6774 .Case("atomic", true)
6775 .Case("getter", true)
6776 .Case("setter", true)
6777 .Case("strong", true)
6778 .Case("weak", true)
6779 .Default(false))
6780 Tokens[I].int_data[0] = CXToken_Keyword;
6781 }
6782 continue;
6783 }
6784
6785 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6786 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6787 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6788 if (llvm::StringSwitch<bool>(II->getName())
6789 .Case("in", true)
6790 .Case("out", true)
6791 .Case("inout", true)
6792 .Case("oneway", true)
6793 .Case("bycopy", true)
6794 .Case("byref", true)
6795 .Default(false))
6796 Tokens[I].int_data[0] = CXToken_Keyword;
6797 continue;
6798 }
6799
6800 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6801 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6802 Tokens[I].int_data[0] = CXToken_Keyword;
6803 continue;
6804 }
6805 }
6806 }
6807}
6808
6809extern "C" {
6810
6811void clang_annotateTokens(CXTranslationUnit TU,
6812 CXToken *Tokens, unsigned NumTokens,
6813 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006814 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006815 LOG_BAD_TU(TU);
6816 return;
6817 }
6818 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006819 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006820 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006821 }
6822
6823 LOG_FUNC_SECTION {
6824 *Log << TU << ' ';
6825 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6826 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6827 *Log << clang_getRange(bloc, eloc);
6828 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006829
6830 // Any token we don't specifically annotate will have a NULL cursor.
6831 CXCursor C = clang_getNullCursor();
6832 for (unsigned I = 0; I != NumTokens; ++I)
6833 Cursors[I] = C;
6834
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006835 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006836 if (!CXXUnit)
6837 return;
6838
6839 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006840
6841 auto AnnotateTokensImpl = [=]() {
6842 clang_annotateTokensImpl(TU, CXXUnit, Tokens, NumTokens, Cursors);
6843 };
Guy Benyei11169dd2012-12-18 14:30:41 +00006844 llvm::CrashRecoveryContext CRC;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006845 if (!RunSafely(CRC, AnnotateTokensImpl, GetSafetyThreadStackSize() * 2)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006846 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6847 }
6848}
6849
6850} // end: extern "C"
6851
6852//===----------------------------------------------------------------------===//
6853// Operations for querying linkage of a cursor.
6854//===----------------------------------------------------------------------===//
6855
6856extern "C" {
6857CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6858 if (!clang_isDeclaration(cursor.kind))
6859 return CXLinkage_Invalid;
6860
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006861 const Decl *D = cxcursor::getCursorDecl(cursor);
6862 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006863 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006864 case NoLinkage:
6865 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006866 case InternalLinkage: return CXLinkage_Internal;
6867 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6868 case ExternalLinkage: return CXLinkage_External;
6869 };
6870
6871 return CXLinkage_Invalid;
6872}
6873} // end: extern "C"
6874
6875//===----------------------------------------------------------------------===//
Ehsan Akhgari93697fa2015-11-23 19:56:46 +00006876// Operations for querying visibility of a cursor.
6877//===----------------------------------------------------------------------===//
6878
6879extern "C" {
6880CXVisibilityKind clang_getCursorVisibility(CXCursor cursor) {
6881 if (!clang_isDeclaration(cursor.kind))
6882 return CXVisibility_Invalid;
6883
6884 const Decl *D = cxcursor::getCursorDecl(cursor);
6885 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
6886 switch (ND->getVisibility()) {
6887 case HiddenVisibility: return CXVisibility_Hidden;
6888 case ProtectedVisibility: return CXVisibility_Protected;
6889 case DefaultVisibility: return CXVisibility_Default;
6890 };
6891
6892 return CXVisibility_Invalid;
6893}
6894} // end: extern "C"
6895
6896//===----------------------------------------------------------------------===//
Guy Benyei11169dd2012-12-18 14:30:41 +00006897// Operations for querying language of a cursor.
6898//===----------------------------------------------------------------------===//
6899
6900static CXLanguageKind getDeclLanguage(const Decl *D) {
6901 if (!D)
6902 return CXLanguage_C;
6903
6904 switch (D->getKind()) {
6905 default:
6906 break;
6907 case Decl::ImplicitParam:
6908 case Decl::ObjCAtDefsField:
6909 case Decl::ObjCCategory:
6910 case Decl::ObjCCategoryImpl:
6911 case Decl::ObjCCompatibleAlias:
6912 case Decl::ObjCImplementation:
6913 case Decl::ObjCInterface:
6914 case Decl::ObjCIvar:
6915 case Decl::ObjCMethod:
6916 case Decl::ObjCProperty:
6917 case Decl::ObjCPropertyImpl:
6918 case Decl::ObjCProtocol:
Douglas Gregor85f3f952015-07-07 03:57:15 +00006919 case Decl::ObjCTypeParam:
Guy Benyei11169dd2012-12-18 14:30:41 +00006920 return CXLanguage_ObjC;
6921 case Decl::CXXConstructor:
6922 case Decl::CXXConversion:
6923 case Decl::CXXDestructor:
6924 case Decl::CXXMethod:
6925 case Decl::CXXRecord:
6926 case Decl::ClassTemplate:
6927 case Decl::ClassTemplatePartialSpecialization:
6928 case Decl::ClassTemplateSpecialization:
6929 case Decl::Friend:
6930 case Decl::FriendTemplate:
6931 case Decl::FunctionTemplate:
6932 case Decl::LinkageSpec:
6933 case Decl::Namespace:
6934 case Decl::NamespaceAlias:
6935 case Decl::NonTypeTemplateParm:
6936 case Decl::StaticAssert:
6937 case Decl::TemplateTemplateParm:
6938 case Decl::TemplateTypeParm:
6939 case Decl::UnresolvedUsingTypename:
6940 case Decl::UnresolvedUsingValue:
6941 case Decl::Using:
6942 case Decl::UsingDirective:
6943 case Decl::UsingShadow:
6944 return CXLanguage_CPlusPlus;
6945 }
6946
6947 return CXLanguage_C;
6948}
6949
6950extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006951
6952static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6953 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
Manuel Klimek8e3a7ed2015-09-25 17:53:16 +00006954 return CXAvailability_NotAvailable;
Guy Benyei11169dd2012-12-18 14:30:41 +00006955
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006956 switch (D->getAvailability()) {
6957 case AR_Available:
6958 case AR_NotYetIntroduced:
6959 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006960 return getCursorAvailabilityForDecl(
6961 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006962 return CXAvailability_Available;
6963
6964 case AR_Deprecated:
6965 return CXAvailability_Deprecated;
6966
6967 case AR_Unavailable:
6968 return CXAvailability_NotAvailable;
6969 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006970
6971 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006972}
6973
Guy Benyei11169dd2012-12-18 14:30:41 +00006974enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6975 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006976 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6977 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006978
6979 return CXAvailability_Available;
6980}
6981
6982static CXVersion convertVersion(VersionTuple In) {
6983 CXVersion Out = { -1, -1, -1 };
6984 if (In.empty())
6985 return Out;
6986
6987 Out.Major = In.getMajor();
6988
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006989 Optional<unsigned> Minor = In.getMinor();
6990 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006991 Out.Minor = *Minor;
6992 else
6993 return Out;
6994
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006995 Optional<unsigned> Subminor = In.getSubminor();
6996 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006997 Out.Subminor = *Subminor;
6998
6999 return Out;
7000}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007001
7002static int getCursorPlatformAvailabilityForDecl(const Decl *D,
7003 int *always_deprecated,
7004 CXString *deprecated_message,
7005 int *always_unavailable,
7006 CXString *unavailable_message,
7007 CXPlatformAvailability *availability,
7008 int availability_size) {
7009 bool HadAvailAttr = false;
7010 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00007011 for (auto A : D->attrs()) {
7012 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007013 HadAvailAttr = true;
7014 if (always_deprecated)
7015 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00007016 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00007017 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007018 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00007019 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007020 continue;
7021 }
7022
Aaron Ballmanb97112e2014-03-08 22:19:01 +00007023 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007024 HadAvailAttr = true;
7025 if (always_unavailable)
7026 *always_unavailable = 1;
7027 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00007028 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007029 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
7030 }
7031 continue;
7032 }
7033
Aaron Ballmanb97112e2014-03-08 22:19:01 +00007034 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007035 HadAvailAttr = true;
7036 if (N < availability_size) {
7037 availability[N].Platform
7038 = cxstring::createDup(Avail->getPlatform()->getName());
7039 availability[N].Introduced = convertVersion(Avail->getIntroduced());
7040 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
7041 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
7042 availability[N].Unavailable = Avail->getUnavailable();
7043 availability[N].Message = cxstring::createDup(Avail->getMessage());
7044 }
7045 ++N;
7046 }
7047 }
7048
7049 if (!HadAvailAttr)
7050 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
7051 return getCursorPlatformAvailabilityForDecl(
7052 cast<Decl>(EnumConst->getDeclContext()),
7053 always_deprecated,
7054 deprecated_message,
7055 always_unavailable,
7056 unavailable_message,
7057 availability,
7058 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00007059
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007060 return N;
7061}
7062
Guy Benyei11169dd2012-12-18 14:30:41 +00007063int clang_getCursorPlatformAvailability(CXCursor cursor,
7064 int *always_deprecated,
7065 CXString *deprecated_message,
7066 int *always_unavailable,
7067 CXString *unavailable_message,
7068 CXPlatformAvailability *availability,
7069 int availability_size) {
7070 if (always_deprecated)
7071 *always_deprecated = 0;
7072 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007073 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00007074 if (always_unavailable)
7075 *always_unavailable = 0;
7076 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007077 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007078
Guy Benyei11169dd2012-12-18 14:30:41 +00007079 if (!clang_isDeclaration(cursor.kind))
7080 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007081
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007082 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00007083 if (!D)
7084 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007085
7086 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
7087 deprecated_message,
7088 always_unavailable,
7089 unavailable_message,
7090 availability,
7091 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00007092}
7093
7094void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
7095 clang_disposeString(availability->Platform);
7096 clang_disposeString(availability->Message);
7097}
7098
7099CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
7100 if (clang_isDeclaration(cursor.kind))
7101 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
7102
7103 return CXLanguage_Invalid;
7104}
7105
7106 /// \brief If the given cursor is the "templated" declaration
7107 /// descibing a class or function template, return the class or
7108 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007109static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007110 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00007111 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007112
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007113 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00007114 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
7115 return FunTmpl;
7116
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007117 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00007118 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
7119 return ClassTmpl;
7120
7121 return D;
7122}
7123
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00007124
7125enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
7126 StorageClass sc = SC_None;
7127 const Decl *D = getCursorDecl(C);
7128 if (D) {
7129 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
7130 sc = FD->getStorageClass();
7131 } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
7132 sc = VD->getStorageClass();
7133 } else {
7134 return CX_SC_Invalid;
7135 }
7136 } else {
7137 return CX_SC_Invalid;
7138 }
7139 switch (sc) {
7140 case SC_None:
7141 return CX_SC_None;
7142 case SC_Extern:
7143 return CX_SC_Extern;
7144 case SC_Static:
7145 return CX_SC_Static;
7146 case SC_PrivateExtern:
7147 return CX_SC_PrivateExtern;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00007148 case SC_Auto:
7149 return CX_SC_Auto;
7150 case SC_Register:
7151 return CX_SC_Register;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00007152 }
Kaelyn Takataab61e702014-10-15 18:03:26 +00007153 llvm_unreachable("Unhandled storage class!");
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00007154}
7155
Guy Benyei11169dd2012-12-18 14:30:41 +00007156CXCursor clang_getCursorSemanticParent(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->getDeclContext();
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 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007169 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00007170 return MakeCXCursor(D, getCursorTU(cursor));
7171 }
7172
7173 return clang_getNullCursor();
7174}
7175
7176CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
7177 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007178 if (const Decl *D = getCursorDecl(cursor)) {
7179 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00007180 if (!DC)
7181 return clang_getNullCursor();
7182
7183 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
7184 getCursorTU(cursor));
7185 }
7186 }
7187
7188 // FIXME: Note that we can't easily compute the lexical context of a
7189 // statement or expression, so we return nothing.
7190 return clang_getNullCursor();
7191}
7192
7193CXFile clang_getIncludedFile(CXCursor cursor) {
7194 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00007195 return nullptr;
7196
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007197 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00007198 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00007199}
7200
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00007201unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
7202 if (C.kind != CXCursor_ObjCPropertyDecl)
7203 return CXObjCPropertyAttr_noattr;
7204
7205 unsigned Result = CXObjCPropertyAttr_noattr;
7206 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
7207 ObjCPropertyDecl::PropertyAttributeKind Attr =
7208 PD->getPropertyAttributesAsWritten();
7209
7210#define SET_CXOBJCPROP_ATTR(A) \
7211 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
7212 Result |= CXObjCPropertyAttr_##A
7213 SET_CXOBJCPROP_ATTR(readonly);
7214 SET_CXOBJCPROP_ATTR(getter);
7215 SET_CXOBJCPROP_ATTR(assign);
7216 SET_CXOBJCPROP_ATTR(readwrite);
7217 SET_CXOBJCPROP_ATTR(retain);
7218 SET_CXOBJCPROP_ATTR(copy);
7219 SET_CXOBJCPROP_ATTR(nonatomic);
7220 SET_CXOBJCPROP_ATTR(setter);
7221 SET_CXOBJCPROP_ATTR(atomic);
7222 SET_CXOBJCPROP_ATTR(weak);
7223 SET_CXOBJCPROP_ATTR(strong);
7224 SET_CXOBJCPROP_ATTR(unsafe_unretained);
7225#undef SET_CXOBJCPROP_ATTR
7226
7227 return Result;
7228}
7229
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00007230unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
7231 if (!clang_isDeclaration(C.kind))
7232 return CXObjCDeclQualifier_None;
7233
7234 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
7235 const Decl *D = getCursorDecl(C);
7236 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
7237 QT = MD->getObjCDeclQualifier();
7238 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
7239 QT = PD->getObjCDeclQualifier();
7240 if (QT == Decl::OBJC_TQ_None)
7241 return CXObjCDeclQualifier_None;
7242
7243 unsigned Result = CXObjCDeclQualifier_None;
7244 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
7245 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
7246 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
7247 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
7248 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
7249 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
7250
7251 return Result;
7252}
7253
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00007254unsigned clang_Cursor_isObjCOptional(CXCursor C) {
7255 if (!clang_isDeclaration(C.kind))
7256 return 0;
7257
7258 const Decl *D = getCursorDecl(C);
7259 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
7260 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
7261 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
7262 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
7263
7264 return 0;
7265}
7266
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00007267unsigned clang_Cursor_isVariadic(CXCursor C) {
7268 if (!clang_isDeclaration(C.kind))
7269 return 0;
7270
7271 const Decl *D = getCursorDecl(C);
7272 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
7273 return FD->isVariadic();
7274 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
7275 return MD->isVariadic();
7276
7277 return 0;
7278}
7279
Guy Benyei11169dd2012-12-18 14:30:41 +00007280CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
7281 if (!clang_isDeclaration(C.kind))
7282 return clang_getNullRange();
7283
7284 const Decl *D = getCursorDecl(C);
7285 ASTContext &Context = getCursorContext(C);
7286 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
7287 if (!RC)
7288 return clang_getNullRange();
7289
7290 return cxloc::translateSourceRange(Context, RC->getSourceRange());
7291}
7292
7293CXString clang_Cursor_getRawCommentText(CXCursor C) {
7294 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00007295 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00007296
7297 const Decl *D = getCursorDecl(C);
7298 ASTContext &Context = getCursorContext(C);
7299 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
7300 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
7301 StringRef();
7302
7303 // Don't duplicate the string because RawText points directly into source
7304 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007305 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00007306}
7307
7308CXString clang_Cursor_getBriefCommentText(CXCursor C) {
7309 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00007310 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00007311
7312 const Decl *D = getCursorDecl(C);
7313 const ASTContext &Context = getCursorContext(C);
7314 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
7315
7316 if (RC) {
7317 StringRef BriefText = RC->getBriefText(Context);
7318
7319 // Don't duplicate the string because RawComment ensures that this memory
7320 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007321 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00007322 }
7323
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00007324 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00007325}
7326
Guy Benyei11169dd2012-12-18 14:30:41 +00007327CXModule clang_Cursor_getModule(CXCursor C) {
7328 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007329 if (const ImportDecl *ImportD =
7330 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00007331 return ImportD->getImportedModule();
7332 }
7333
Craig Topper69186e72014-06-08 08:38:04 +00007334 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007335}
7336
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00007337CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
7338 if (isNotUsableTU(TU)) {
7339 LOG_BAD_TU(TU);
7340 return nullptr;
7341 }
7342 if (!File)
7343 return nullptr;
7344 FileEntry *FE = static_cast<FileEntry *>(File);
7345
7346 ASTUnit &Unit = *cxtu::getASTUnit(TU);
7347 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
7348 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
7349
Richard Smithfeb54b62014-10-23 02:01:19 +00007350 return Header.getModule();
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00007351}
7352
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00007353CXFile clang_Module_getASTFile(CXModule CXMod) {
7354 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00007355 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00007356 Module *Mod = static_cast<Module*>(CXMod);
7357 return const_cast<FileEntry *>(Mod->getASTFile());
7358}
7359
Guy Benyei11169dd2012-12-18 14:30:41 +00007360CXModule clang_Module_getParent(CXModule CXMod) {
7361 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00007362 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007363 Module *Mod = static_cast<Module*>(CXMod);
7364 return Mod->Parent;
7365}
7366
7367CXString clang_Module_getName(CXModule CXMod) {
7368 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007369 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00007370 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007371 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00007372}
7373
7374CXString clang_Module_getFullName(CXModule CXMod) {
7375 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007376 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00007377 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007378 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00007379}
7380
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00007381int clang_Module_isSystem(CXModule CXMod) {
7382 if (!CXMod)
7383 return 0;
7384 Module *Mod = static_cast<Module*>(CXMod);
7385 return Mod->IsSystem;
7386}
7387
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007388unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
7389 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007390 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007391 LOG_BAD_TU(TU);
7392 return 0;
7393 }
7394 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00007395 return 0;
7396 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007397 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
7398 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
7399 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00007400}
7401
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007402CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
7403 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007404 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007405 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00007406 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007407 }
7408 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00007409 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007410 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007411 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00007412
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007413 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
7414 if (Index < TopHeaders.size())
7415 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00007416
Craig Topper69186e72014-06-08 08:38:04 +00007417 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007418}
7419
7420} // end: extern "C"
7421
7422//===----------------------------------------------------------------------===//
7423// C++ AST instrospection.
7424//===----------------------------------------------------------------------===//
7425
7426extern "C" {
Saleem Abdulrasool6ea75db2015-10-27 15:50:22 +00007427unsigned clang_CXXField_isMutable(CXCursor C) {
7428 if (!clang_isDeclaration(C.kind))
7429 return 0;
7430
7431 if (const auto D = cxcursor::getCursorDecl(C))
7432 if (const auto FD = dyn_cast_or_null<FieldDecl>(D))
7433 return FD->isMutable() ? 1 : 0;
7434 return 0;
7435}
7436
Dmitri Gribenko62770be2013-05-17 18:38:35 +00007437unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
7438 if (!clang_isDeclaration(C.kind))
7439 return 0;
7440
Dmitri Gribenko62770be2013-05-17 18:38:35 +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;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00007444 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
7445}
7446
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00007447unsigned clang_CXXMethod_isConst(CXCursor C) {
7448 if (!clang_isDeclaration(C.kind))
7449 return 0;
7450
7451 const Decl *D = cxcursor::getCursorDecl(C);
7452 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007453 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00007454 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
7455}
7456
Guy Benyei11169dd2012-12-18 14:30:41 +00007457unsigned clang_CXXMethod_isStatic(CXCursor C) {
7458 if (!clang_isDeclaration(C.kind))
7459 return 0;
7460
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007461 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007462 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007463 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007464 return (Method && Method->isStatic()) ? 1 : 0;
7465}
7466
7467unsigned clang_CXXMethod_isVirtual(CXCursor C) {
7468 if (!clang_isDeclaration(C.kind))
7469 return 0;
7470
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007471 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007472 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007473 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007474 return (Method && Method->isVirtual()) ? 1 : 0;
7475}
7476} // end: extern "C"
7477
7478//===----------------------------------------------------------------------===//
7479// Attribute introspection.
7480//===----------------------------------------------------------------------===//
7481
7482extern "C" {
7483CXType clang_getIBOutletCollectionType(CXCursor C) {
7484 if (C.kind != CXCursor_IBOutletCollectionAttr)
7485 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
7486
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00007487 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00007488 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
7489
7490 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
7491}
7492} // end: extern "C"
7493
7494//===----------------------------------------------------------------------===//
7495// Inspecting memory usage.
7496//===----------------------------------------------------------------------===//
7497
7498typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
7499
7500static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
7501 enum CXTUResourceUsageKind k,
7502 unsigned long amount) {
7503 CXTUResourceUsageEntry entry = { k, amount };
7504 entries.push_back(entry);
7505}
7506
7507extern "C" {
7508
7509const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
7510 const char *str = "";
7511 switch (kind) {
7512 case CXTUResourceUsage_AST:
7513 str = "ASTContext: expressions, declarations, and types";
7514 break;
7515 case CXTUResourceUsage_Identifiers:
7516 str = "ASTContext: identifiers";
7517 break;
7518 case CXTUResourceUsage_Selectors:
7519 str = "ASTContext: selectors";
7520 break;
7521 case CXTUResourceUsage_GlobalCompletionResults:
7522 str = "Code completion: cached global results";
7523 break;
7524 case CXTUResourceUsage_SourceManagerContentCache:
7525 str = "SourceManager: content cache allocator";
7526 break;
7527 case CXTUResourceUsage_AST_SideTables:
7528 str = "ASTContext: side tables";
7529 break;
7530 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
7531 str = "SourceManager: malloc'ed memory buffers";
7532 break;
7533 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
7534 str = "SourceManager: mmap'ed memory buffers";
7535 break;
7536 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
7537 str = "ExternalASTSource: malloc'ed memory buffers";
7538 break;
7539 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
7540 str = "ExternalASTSource: mmap'ed memory buffers";
7541 break;
7542 case CXTUResourceUsage_Preprocessor:
7543 str = "Preprocessor: malloc'ed memory";
7544 break;
7545 case CXTUResourceUsage_PreprocessingRecord:
7546 str = "Preprocessor: PreprocessingRecord";
7547 break;
7548 case CXTUResourceUsage_SourceManager_DataStructures:
7549 str = "SourceManager: data structures and tables";
7550 break;
7551 case CXTUResourceUsage_Preprocessor_HeaderSearch:
7552 str = "Preprocessor: header search tables";
7553 break;
7554 }
7555 return str;
7556}
7557
7558CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007559 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007560 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00007561 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00007562 return usage;
7563 }
7564
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007565 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00007566 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00007567 ASTContext &astContext = astUnit->getASTContext();
7568
7569 // How much memory is used by AST nodes and types?
7570 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
7571 (unsigned long) astContext.getASTAllocatedMemory());
7572
7573 // How much memory is used by identifiers?
7574 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
7575 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
7576
7577 // How much memory is used for selectors?
7578 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
7579 (unsigned long) astContext.Selectors.getTotalMemory());
7580
7581 // How much memory is used by ASTContext's side tables?
7582 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
7583 (unsigned long) astContext.getSideTableAllocatedMemory());
7584
7585 // How much memory is used for caching global code completion results?
7586 unsigned long completionBytes = 0;
7587 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00007588 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007589 completionBytes = completionAllocator->getTotalMemory();
7590 }
7591 createCXTUResourceUsageEntry(*entries,
7592 CXTUResourceUsage_GlobalCompletionResults,
7593 completionBytes);
7594
7595 // How much memory is being used by SourceManager's content cache?
7596 createCXTUResourceUsageEntry(*entries,
7597 CXTUResourceUsage_SourceManagerContentCache,
7598 (unsigned long) astContext.getSourceManager().getContentCacheSize());
7599
7600 // How much memory is being used by the MemoryBuffer's in SourceManager?
7601 const SourceManager::MemoryBufferSizes &srcBufs =
7602 astUnit->getSourceManager().getMemoryBufferSizes();
7603
7604 createCXTUResourceUsageEntry(*entries,
7605 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
7606 (unsigned long) srcBufs.malloc_bytes);
7607 createCXTUResourceUsageEntry(*entries,
7608 CXTUResourceUsage_SourceManager_Membuffer_MMap,
7609 (unsigned long) srcBufs.mmap_bytes);
7610 createCXTUResourceUsageEntry(*entries,
7611 CXTUResourceUsage_SourceManager_DataStructures,
7612 (unsigned long) astContext.getSourceManager()
7613 .getDataStructureSizes());
7614
7615 // How much memory is being used by the ExternalASTSource?
7616 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
7617 const ExternalASTSource::MemoryBufferSizes &sizes =
7618 esrc->getMemoryBufferSizes();
7619
7620 createCXTUResourceUsageEntry(*entries,
7621 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
7622 (unsigned long) sizes.malloc_bytes);
7623 createCXTUResourceUsageEntry(*entries,
7624 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
7625 (unsigned long) sizes.mmap_bytes);
7626 }
7627
7628 // How much memory is being used by the Preprocessor?
7629 Preprocessor &pp = astUnit->getPreprocessor();
7630 createCXTUResourceUsageEntry(*entries,
7631 CXTUResourceUsage_Preprocessor,
7632 pp.getTotalMemory());
7633
7634 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
7635 createCXTUResourceUsageEntry(*entries,
7636 CXTUResourceUsage_PreprocessingRecord,
7637 pRec->getTotalMemory());
7638 }
7639
7640 createCXTUResourceUsageEntry(*entries,
7641 CXTUResourceUsage_Preprocessor_HeaderSearch,
7642 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00007643
Guy Benyei11169dd2012-12-18 14:30:41 +00007644 CXTUResourceUsage usage = { (void*) entries.get(),
7645 (unsigned) entries->size(),
Alexander Kornienko6ee521c2015-01-23 15:36:10 +00007646 !entries->empty() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00007647 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00007648 return usage;
7649}
7650
7651void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
7652 if (usage.data)
7653 delete (MemUsageEntries*) usage.data;
7654}
7655
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007656CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
7657 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007658 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00007659 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007660
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007661 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007662 LOG_BAD_TU(TU);
7663 return skipped;
7664 }
7665
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007666 if (!file)
7667 return skipped;
7668
7669 ASTUnit *astUnit = cxtu::getASTUnit(TU);
7670 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
7671 if (!ppRec)
7672 return skipped;
7673
7674 ASTContext &Ctx = astUnit->getASTContext();
7675 SourceManager &sm = Ctx.getSourceManager();
7676 FileEntry *fileEntry = static_cast<FileEntry *>(file);
7677 FileID wantedFileID = sm.translateFile(fileEntry);
7678
7679 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
7680 std::vector<SourceRange> wantedRanges;
7681 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
7682 i != ei; ++i) {
7683 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
7684 wantedRanges.push_back(*i);
7685 }
7686
7687 skipped->count = wantedRanges.size();
7688 skipped->ranges = new CXSourceRange[skipped->count];
7689 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
7690 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
7691
7692 return skipped;
7693}
7694
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007695void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
7696 if (ranges) {
7697 delete[] ranges->ranges;
7698 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007699 }
7700}
7701
Guy Benyei11169dd2012-12-18 14:30:41 +00007702} // end extern "C"
7703
7704void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
7705 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
7706 for (unsigned I = 0; I != Usage.numEntries; ++I)
7707 fprintf(stderr, " %s: %lu\n",
7708 clang_getTUResourceUsageName(Usage.entries[I].kind),
7709 Usage.entries[I].amount);
7710
7711 clang_disposeCXTUResourceUsage(Usage);
7712}
7713
7714//===----------------------------------------------------------------------===//
7715// Misc. utility functions.
7716//===----------------------------------------------------------------------===//
7717
7718/// Default to using an 8 MB stack size on "safety" threads.
7719static unsigned SafetyStackThreadSize = 8 << 20;
7720
7721namespace clang {
7722
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007723bool RunSafely(llvm::CrashRecoveryContext &CRC, llvm::function_ref<void()> Fn,
Guy Benyei11169dd2012-12-18 14:30:41 +00007724 unsigned Size) {
7725 if (!Size)
7726 Size = GetSafetyThreadStackSize();
7727 if (Size)
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007728 return CRC.RunSafelyOnThread(Fn, Size);
7729 return CRC.RunSafely(Fn);
Guy Benyei11169dd2012-12-18 14:30:41 +00007730}
7731
7732unsigned GetSafetyThreadStackSize() {
7733 return SafetyStackThreadSize;
7734}
7735
7736void SetSafetyThreadStackSize(unsigned Value) {
7737 SafetyStackThreadSize = Value;
7738}
7739
Alexander Kornienkoab9db512015-06-22 23:07:51 +00007740}
Guy Benyei11169dd2012-12-18 14:30:41 +00007741
7742void clang::setThreadBackgroundPriority() {
7743 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
7744 return;
7745
Alp Toker1a86ad22014-07-06 06:24:00 +00007746#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00007747 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
7748#endif
7749}
7750
7751void cxindex::printDiagsToStderr(ASTUnit *Unit) {
7752 if (!Unit)
7753 return;
7754
7755 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
7756 DEnd = Unit->stored_diag_end();
7757 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00007758 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00007759 CXString Msg = clang_formatDiagnostic(&Diag,
7760 clang_defaultDiagnosticDisplayOptions());
7761 fprintf(stderr, "%s\n", clang_getCString(Msg));
7762 clang_disposeString(Msg);
7763 }
7764#ifdef LLVM_ON_WIN32
7765 // On Windows, force a flush, since there may be multiple copies of
7766 // stderr and stdout in the file system, all with different buffers
7767 // but writing to the same device.
7768 fflush(stderr);
7769#endif
7770}
7771
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007772MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
7773 SourceLocation MacroDefLoc,
7774 CXTranslationUnit TU){
7775 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007776 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007777 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007778 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007779
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007780 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007781 Preprocessor &PP = Unit->getPreprocessor();
Richard Smith20e883e2015-04-29 23:20:19 +00007782 MacroDirective *MD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007783 if (MD) {
7784 for (MacroDirective::DefInfo
7785 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
7786 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
7787 return Def.getMacroInfo();
7788 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007789 }
7790
Craig Topper69186e72014-06-08 08:38:04 +00007791 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007792}
7793
Richard Smith66a81862015-05-04 02:25:31 +00007794const MacroInfo *cxindex::getMacroInfo(const MacroDefinitionRecord *MacroDef,
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007795 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007796 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007797 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007798 const IdentifierInfo *II = MacroDef->getName();
7799 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00007800 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007801
7802 return getMacroInfo(*II, MacroDef->getLocation(), TU);
7803}
7804
Richard Smith66a81862015-05-04 02:25:31 +00007805MacroDefinitionRecord *
7806cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, const Token &Tok,
7807 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007808 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007809 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007810 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00007811 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007812
7813 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007814 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007815 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
7816 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007817 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007818
7819 // Check that the token is inside the definition and not its argument list.
7820 SourceManager &SM = Unit->getSourceManager();
7821 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00007822 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007823 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00007824 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007825
7826 Preprocessor &PP = Unit->getPreprocessor();
7827 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
7828 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00007829 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007830
Alp Toker2d57cea2014-05-17 04:53:25 +00007831 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007832 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007833 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007834
7835 // Check that the identifier is not one of the macro arguments.
7836 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00007837 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007838
Richard Smith20e883e2015-04-29 23:20:19 +00007839 MacroDirective *InnerMD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007840 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00007841 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007842
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007843 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007844}
7845
Richard Smith66a81862015-05-04 02:25:31 +00007846MacroDefinitionRecord *
7847cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, SourceLocation Loc,
7848 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007849 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007850 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007851
7852 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007853 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007854 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007855 Preprocessor &PP = Unit->getPreprocessor();
7856 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00007857 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007858 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7859 Token Tok;
7860 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00007861 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007862
7863 return checkForMacroInMacroDefinition(MI, Tok, TU);
7864}
7865
Guy Benyei11169dd2012-12-18 14:30:41 +00007866extern "C" {
7867
7868CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007869 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00007870}
7871
7872} // end: extern "C"
7873
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007874Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7875 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007876 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007877 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007878 if (Unit->isMainFileAST())
7879 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007880 return *this;
7881 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007882 } else {
7883 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007884 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007885 return *this;
7886}
7887
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007888Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7889 *this << FE->getName();
7890 return *this;
7891}
7892
7893Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7894 CXString cursorName = clang_getCursorDisplayName(cursor);
7895 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7896 clang_disposeString(cursorName);
7897 return *this;
7898}
7899
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007900Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7901 CXFile File;
7902 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007903 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007904 CXString FileName = clang_getFileName(File);
7905 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7906 clang_disposeString(FileName);
7907 return *this;
7908}
7909
7910Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7911 CXSourceLocation BLoc = clang_getRangeStart(range);
7912 CXSourceLocation ELoc = clang_getRangeEnd(range);
7913
7914 CXFile BFile;
7915 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007916 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007917
7918 CXFile EFile;
7919 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007920 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007921
7922 CXString BFileName = clang_getFileName(BFile);
7923 if (BFile == EFile) {
7924 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7925 BLine, BColumn, ELine, EColumn);
7926 } else {
7927 CXString EFileName = clang_getFileName(EFile);
7928 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7929 BLine, BColumn)
7930 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7931 ELine, EColumn);
7932 clang_disposeString(EFileName);
7933 }
7934 clang_disposeString(BFileName);
7935 return *this;
7936}
7937
7938Logger &cxindex::Logger::operator<<(CXString Str) {
7939 *this << clang_getCString(Str);
7940 return *this;
7941}
7942
7943Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7944 LogOS << Fmt;
7945 return *this;
7946}
7947
Chandler Carruth37ad2582014-06-27 15:14:39 +00007948static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7949
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007950cxindex::Logger::~Logger() {
Chandler Carruth37ad2582014-06-27 15:14:39 +00007951 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007952
7953 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7954
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007955 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007956 OS << "[libclang:" << Name << ':';
7957
Alp Toker1a86ad22014-07-06 06:24:00 +00007958#ifdef USE_DARWIN_THREADS
7959 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007960 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7961 OS << tid << ':';
7962#endif
7963
7964 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7965 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
Yaron Keren09fb7c62015-03-10 07:33:23 +00007966 OS << Msg << '\n';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007967
7968 if (Trace) {
Zachary Turner1fe2a8d2015-03-05 19:15:09 +00007969 llvm::sys::PrintStackTrace(OS);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007970 OS << "--------------------------------------------------\n";
7971 }
7972}