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