blob: 24dde235605f9813532cf1e92b0bc21f87e16cf9 [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}
Arpith Chacko Jacob3cf89042016-01-26 16:37:23 +00002232void OMPClauseEnqueue::VisitOMPDefaultmapClause(const OMPDefaultmapClause *C) {
2233}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002234}
Alexey Bataev756c1962013-09-24 03:17:45 +00002235
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002236void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2237 unsigned size = WL.size();
2238 OMPClauseEnqueue Visitor(this);
2239 Visitor.Visit(S);
2240 if (size == WL.size())
2241 return;
2242 // Now reverse the entries we just added. This will match the DFS
2243 // ordering performed by the worklist.
2244 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2245 std::reverse(I, E);
2246}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002247void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002248 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2249}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002250void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002251 AddDecl(B->getBlockDecl());
2252}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002253void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002254 EnqueueChildren(E);
2255 AddTypeLoc(E->getTypeSourceInfo());
2256}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002257void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
Pete Cooper57d3f142015-07-30 17:22:52 +00002258 for (auto &I : llvm::reverse(S->body()))
2259 AddStmt(I);
Guy Benyei11169dd2012-12-18 14:30:41 +00002260}
2261void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002262VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002263 AddStmt(S->getSubStmt());
2264 AddDeclarationNameInfo(S);
2265 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2266 AddNestedNameSpecifierLoc(QualifierLoc);
2267}
2268
2269void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002270VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002271 if (E->hasExplicitTemplateArgs())
2272 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002273 AddDeclarationNameInfo(E);
2274 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2275 AddNestedNameSpecifierLoc(QualifierLoc);
2276 if (!E->isImplicitAccess())
2277 AddStmt(E->getBase());
2278}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002279void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002280 // Enqueue the initializer , if any.
2281 AddStmt(E->getInitializer());
2282 // Enqueue the array size, if any.
2283 AddStmt(E->getArraySize());
2284 // Enqueue the allocated type.
2285 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2286 // Enqueue the placement arguments.
2287 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2288 AddStmt(E->getPlacementArg(I-1));
2289}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002290void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002291 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2292 AddStmt(CE->getArg(I-1));
2293 AddStmt(CE->getCallee());
2294 AddStmt(CE->getArg(0));
2295}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002296void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2297 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002298 // Visit the name of the type being destroyed.
2299 AddTypeLoc(E->getDestroyedTypeInfo());
2300 // Visit the scope type that looks disturbingly like the nested-name-specifier
2301 // but isn't.
2302 AddTypeLoc(E->getScopeTypeInfo());
2303 // Visit the nested-name-specifier.
2304 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2305 AddNestedNameSpecifierLoc(QualifierLoc);
2306 // Visit base expression.
2307 AddStmt(E->getBase());
2308}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002309void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2310 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002311 AddTypeLoc(E->getTypeSourceInfo());
2312}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002313void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2314 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002315 EnqueueChildren(E);
2316 AddTypeLoc(E->getTypeSourceInfo());
2317}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002318void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002319 EnqueueChildren(E);
2320 if (E->isTypeOperand())
2321 AddTypeLoc(E->getTypeOperandSourceInfo());
2322}
2323
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002324void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2325 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002326 EnqueueChildren(E);
2327 AddTypeLoc(E->getTypeSourceInfo());
2328}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002329void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002330 EnqueueChildren(E);
2331 if (E->isTypeOperand())
2332 AddTypeLoc(E->getTypeOperandSourceInfo());
2333}
2334
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002335void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002336 EnqueueChildren(S);
2337 AddDecl(S->getExceptionDecl());
2338}
2339
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002340void EnqueueVisitor::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002341 AddStmt(S->getBody());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002342 AddStmt(S->getRangeInit());
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002343 AddDecl(S->getLoopVariable());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002344}
2345
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002346void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002347 if (DR->hasExplicitTemplateArgs())
2348 AddExplicitTemplateArgs(DR->getTemplateArgs(), DR->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002349 WL.push_back(DeclRefExprParts(DR, Parent));
2350}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002351void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2352 const DependentScopeDeclRefExpr *E) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002353 if (E->hasExplicitTemplateArgs())
2354 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002355 AddDeclarationNameInfo(E);
2356 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2357}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002358void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002359 unsigned size = WL.size();
2360 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002361 for (const auto *D : S->decls()) {
2362 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002363 isFirst = false;
2364 }
2365 if (size == WL.size())
2366 return;
2367 // Now reverse the entries we just added. This will match the DFS
2368 // ordering performed by the worklist.
2369 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2370 std::reverse(I, E);
2371}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002372void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002373 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002374 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002375 D = E->designators_rbegin(), DEnd = E->designators_rend();
2376 D != DEnd; ++D) {
2377 if (D->isFieldDesignator()) {
2378 if (FieldDecl *Field = D->getField())
2379 AddMemberRef(Field, D->getFieldLoc());
2380 continue;
2381 }
2382 if (D->isArrayDesignator()) {
2383 AddStmt(E->getArrayIndex(*D));
2384 continue;
2385 }
2386 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2387 AddStmt(E->getArrayRangeEnd(*D));
2388 AddStmt(E->getArrayRangeStart(*D));
2389 }
2390}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002391void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002392 EnqueueChildren(E);
2393 AddTypeLoc(E->getTypeInfoAsWritten());
2394}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002395void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002396 AddStmt(FS->getBody());
2397 AddStmt(FS->getInc());
2398 AddStmt(FS->getCond());
2399 AddDecl(FS->getConditionVariable());
2400 AddStmt(FS->getInit());
2401}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002402void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002403 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2404}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002405void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002406 AddStmt(If->getElse());
2407 AddStmt(If->getThen());
2408 AddStmt(If->getCond());
2409 AddDecl(If->getConditionVariable());
2410}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002411void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002412 // We care about the syntactic form of the initializer list, only.
2413 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2414 IE = Syntactic;
2415 EnqueueChildren(IE);
2416}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002417void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002418 WL.push_back(MemberExprParts(M, Parent));
2419
2420 // If the base of the member access expression is an implicit 'this', don't
2421 // visit it.
2422 // FIXME: If we ever want to show these implicit accesses, this will be
2423 // unfortunate. However, clang_getCursor() relies on this behavior.
Argyrios Kyrtzidis58d0e7a2015-03-13 04:40:07 +00002424 if (M->isImplicitAccess())
2425 return;
2426
2427 // Ignore base anonymous struct/union fields, otherwise they will shadow the
2428 // real field that that we are interested in.
2429 if (auto *SubME = dyn_cast<MemberExpr>(M->getBase())) {
2430 if (auto *FD = dyn_cast_or_null<FieldDecl>(SubME->getMemberDecl())) {
2431 if (FD->isAnonymousStructOrUnion()) {
2432 AddStmt(SubME->getBase());
2433 return;
2434 }
2435 }
2436 }
2437
2438 AddStmt(M->getBase());
Guy Benyei11169dd2012-12-18 14:30:41 +00002439}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002440void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002441 AddTypeLoc(E->getEncodedTypeSourceInfo());
2442}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002443void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002444 EnqueueChildren(M);
2445 AddTypeLoc(M->getClassReceiverTypeInfo());
2446}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002447void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002448 // Visit the components of the offsetof expression.
2449 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002450 const OffsetOfNode &Node = E->getComponent(I-1);
2451 switch (Node.getKind()) {
2452 case OffsetOfNode::Array:
2453 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2454 break;
2455 case OffsetOfNode::Field:
2456 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2457 break;
2458 case OffsetOfNode::Identifier:
2459 case OffsetOfNode::Base:
2460 continue;
2461 }
2462 }
2463 // Visit the type into which we're computing the offset.
2464 AddTypeLoc(E->getTypeSourceInfo());
2465}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002466void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002467 if (E->hasExplicitTemplateArgs())
2468 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002469 WL.push_back(OverloadExprParts(E, Parent));
2470}
2471void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002472 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002473 EnqueueChildren(E);
2474 if (E->isArgumentType())
2475 AddTypeLoc(E->getArgumentTypeInfo());
2476}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002477void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002478 EnqueueChildren(S);
2479}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002480void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002481 AddStmt(S->getBody());
2482 AddStmt(S->getCond());
2483 AddDecl(S->getConditionVariable());
2484}
2485
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002486void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002487 AddStmt(W->getBody());
2488 AddStmt(W->getCond());
2489 AddDecl(W->getConditionVariable());
2490}
2491
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002492void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002493 for (unsigned I = E->getNumArgs(); I > 0; --I)
2494 AddTypeLoc(E->getArg(I-1));
2495}
2496
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002497void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002498 AddTypeLoc(E->getQueriedTypeSourceInfo());
2499}
2500
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002501void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002502 EnqueueChildren(E);
2503}
2504
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002505void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002506 VisitOverloadExpr(U);
2507 if (!U->isImplicitAccess())
2508 AddStmt(U->getBase());
2509}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002510void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002511 AddStmt(E->getSubExpr());
2512 AddTypeLoc(E->getWrittenTypeInfo());
2513}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002514void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002515 WL.push_back(SizeOfPackExprParts(E, Parent));
2516}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002517void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002518 // If the opaque value has a source expression, just transparently
2519 // visit that. This is useful for (e.g.) pseudo-object expressions.
2520 if (Expr *SourceExpr = E->getSourceExpr())
2521 return Visit(SourceExpr);
2522}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002523void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002524 AddStmt(E->getBody());
2525 WL.push_back(LambdaExprParts(E, Parent));
2526}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002527void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002528 // Treat the expression like its syntactic form.
2529 Visit(E->getSyntacticForm());
2530}
2531
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002532void EnqueueVisitor::VisitOMPExecutableDirective(
2533 const OMPExecutableDirective *D) {
2534 EnqueueChildren(D);
2535 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2536 E = D->clauses().end();
2537 I != E; ++I)
2538 EnqueueChildren(*I);
2539}
2540
Alexander Musman3aaab662014-08-19 11:27:13 +00002541void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
2542 VisitOMPExecutableDirective(D);
2543}
2544
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002545void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2546 VisitOMPExecutableDirective(D);
2547}
2548
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002549void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002550 VisitOMPLoopDirective(D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002551}
2552
Alexey Bataevf29276e2014-06-18 04:14:57 +00002553void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002554 VisitOMPLoopDirective(D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002555}
2556
Alexander Musmanf82886e2014-09-18 05:12:34 +00002557void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
2558 VisitOMPLoopDirective(D);
2559}
2560
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002561void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2562 VisitOMPExecutableDirective(D);
2563}
2564
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002565void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2566 VisitOMPExecutableDirective(D);
2567}
2568
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002569void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2570 VisitOMPExecutableDirective(D);
2571}
2572
Alexander Musman80c22892014-07-17 08:54:58 +00002573void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2574 VisitOMPExecutableDirective(D);
2575}
2576
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002577void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2578 VisitOMPExecutableDirective(D);
2579 AddDeclarationNameInfo(D);
2580}
2581
Alexey Bataev4acb8592014-07-07 13:01:15 +00002582void
2583EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002584 VisitOMPLoopDirective(D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002585}
2586
Alexander Musmane4e893b2014-09-23 09:33:00 +00002587void EnqueueVisitor::VisitOMPParallelForSimdDirective(
2588 const OMPParallelForSimdDirective *D) {
2589 VisitOMPLoopDirective(D);
2590}
2591
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002592void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2593 const OMPParallelSectionsDirective *D) {
2594 VisitOMPExecutableDirective(D);
2595}
2596
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002597void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2598 VisitOMPExecutableDirective(D);
2599}
2600
Alexey Bataev68446b72014-07-18 07:47:19 +00002601void
2602EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2603 VisitOMPExecutableDirective(D);
2604}
2605
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002606void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2607 VisitOMPExecutableDirective(D);
2608}
2609
Alexey Bataev2df347a2014-07-18 10:17:07 +00002610void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2611 VisitOMPExecutableDirective(D);
2612}
2613
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002614void EnqueueVisitor::VisitOMPTaskgroupDirective(
2615 const OMPTaskgroupDirective *D) {
2616 VisitOMPExecutableDirective(D);
2617}
2618
Alexey Bataev6125da92014-07-21 11:26:11 +00002619void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2620 VisitOMPExecutableDirective(D);
2621}
2622
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002623void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2624 VisitOMPExecutableDirective(D);
2625}
2626
Alexey Bataev0162e452014-07-22 10:10:35 +00002627void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2628 VisitOMPExecutableDirective(D);
2629}
2630
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002631void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
2632 VisitOMPExecutableDirective(D);
2633}
2634
Michael Wong65f367f2015-07-21 13:44:28 +00002635void EnqueueVisitor::VisitOMPTargetDataDirective(const
2636 OMPTargetDataDirective *D) {
2637 VisitOMPExecutableDirective(D);
2638}
2639
Samuel Antaodf67fc42016-01-19 19:15:56 +00002640void EnqueueVisitor::VisitOMPTargetEnterDataDirective(
2641 const OMPTargetEnterDataDirective *D) {
2642 VisitOMPExecutableDirective(D);
2643}
2644
Samuel Antao72590762016-01-19 20:04:50 +00002645void EnqueueVisitor::VisitOMPTargetExitDataDirective(
2646 const OMPTargetExitDataDirective *D) {
2647 VisitOMPExecutableDirective(D);
2648}
2649
Alexey Bataev13314bf2014-10-09 04:18:56 +00002650void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {
2651 VisitOMPExecutableDirective(D);
2652}
2653
Alexey Bataev6d4ed052015-07-01 06:57:41 +00002654void EnqueueVisitor::VisitOMPCancellationPointDirective(
2655 const OMPCancellationPointDirective *D) {
2656 VisitOMPExecutableDirective(D);
2657}
2658
Alexey Bataev80909872015-07-02 11:25:17 +00002659void EnqueueVisitor::VisitOMPCancelDirective(const OMPCancelDirective *D) {
2660 VisitOMPExecutableDirective(D);
2661}
2662
Alexey Bataev49f6e782015-12-01 04:18:41 +00002663void EnqueueVisitor::VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *D) {
2664 VisitOMPLoopDirective(D);
2665}
2666
Alexey Bataev0a6ed842015-12-03 09:40:15 +00002667void EnqueueVisitor::VisitOMPTaskLoopSimdDirective(
2668 const OMPTaskLoopSimdDirective *D) {
2669 VisitOMPLoopDirective(D);
2670}
2671
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00002672void EnqueueVisitor::VisitOMPDistributeDirective(
2673 const OMPDistributeDirective *D) {
2674 VisitOMPLoopDirective(D);
2675}
2676
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002677void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002678 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2679}
2680
2681bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2682 if (RegionOfInterest.isValid()) {
2683 SourceRange Range = getRawCursorExtent(C);
2684 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2685 return false;
2686 }
2687 return true;
2688}
2689
2690bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2691 while (!WL.empty()) {
2692 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002693 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002694
2695 // Set the Parent field, then back to its old value once we're done.
2696 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2697
2698 switch (LI.getKind()) {
2699 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002700 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002701 if (!D)
2702 continue;
2703
2704 // For now, perform default visitation for Decls.
2705 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2706 cast<DeclVisit>(&LI)->isFirst())))
2707 return true;
2708
2709 continue;
2710 }
2711 case VisitorJob::ExplicitTemplateArgsVisitKind: {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002712 for (const TemplateArgumentLoc &Arg :
2713 *cast<ExplicitTemplateArgsVisit>(&LI)) {
2714 if (VisitTemplateArgumentLoc(Arg))
Guy Benyei11169dd2012-12-18 14:30:41 +00002715 return true;
2716 }
2717 continue;
2718 }
2719 case VisitorJob::TypeLocVisitKind: {
2720 // Perform default visitation for TypeLocs.
2721 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2722 return true;
2723 continue;
2724 }
2725 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002726 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002727 if (LabelStmt *stmt = LS->getStmt()) {
2728 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2729 TU))) {
2730 return true;
2731 }
2732 }
2733 continue;
2734 }
2735
2736 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2737 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2738 if (VisitNestedNameSpecifierLoc(V->get()))
2739 return true;
2740 continue;
2741 }
2742
2743 case VisitorJob::DeclarationNameInfoVisitKind: {
2744 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2745 ->get()))
2746 return true;
2747 continue;
2748 }
2749 case VisitorJob::MemberRefVisitKind: {
2750 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2751 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2752 return true;
2753 continue;
2754 }
2755 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002756 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002757 if (!S)
2758 continue;
2759
2760 // Update the current cursor.
2761 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2762 if (!IsInRegionOfInterest(Cursor))
2763 continue;
2764 switch (Visitor(Cursor, Parent, ClientData)) {
2765 case CXChildVisit_Break: return true;
2766 case CXChildVisit_Continue: break;
2767 case CXChildVisit_Recurse:
2768 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002769 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002770 EnqueueWorkList(WL, S);
2771 break;
2772 }
2773 continue;
2774 }
2775 case VisitorJob::MemberExprPartsKind: {
2776 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002777 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002778
2779 // Visit the nested-name-specifier
2780 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2781 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2782 return true;
2783
2784 // Visit the declaration name.
2785 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2786 return true;
2787
2788 // Visit the explicitly-specified template arguments, if any.
2789 if (M->hasExplicitTemplateArgs()) {
2790 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2791 *ArgEnd = Arg + M->getNumTemplateArgs();
2792 Arg != ArgEnd; ++Arg) {
2793 if (VisitTemplateArgumentLoc(*Arg))
2794 return true;
2795 }
2796 }
2797 continue;
2798 }
2799 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002800 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002801 // Visit nested-name-specifier, if present.
2802 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2803 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2804 return true;
2805 // Visit declaration name.
2806 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2807 return true;
2808 continue;
2809 }
2810 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002811 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002812 // Visit the nested-name-specifier.
2813 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2814 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2815 return true;
2816 // Visit the declaration name.
2817 if (VisitDeclarationNameInfo(O->getNameInfo()))
2818 return true;
2819 // Visit the overloaded declaration reference.
2820 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2821 return true;
2822 continue;
2823 }
2824 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002825 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002826 NamedDecl *Pack = E->getPack();
2827 if (isa<TemplateTypeParmDecl>(Pack)) {
2828 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2829 E->getPackLoc(), TU)))
2830 return true;
2831
2832 continue;
2833 }
2834
2835 if (isa<TemplateTemplateParmDecl>(Pack)) {
2836 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2837 E->getPackLoc(), TU)))
2838 return true;
2839
2840 continue;
2841 }
2842
2843 // Non-type template parameter packs and function parameter packs are
2844 // treated like DeclRefExpr cursors.
2845 continue;
2846 }
2847
2848 case VisitorJob::LambdaExprPartsKind: {
2849 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002850 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002851 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2852 CEnd = E->explicit_capture_end();
2853 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002854 // FIXME: Lambda init-captures.
2855 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002856 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002857
Guy Benyei11169dd2012-12-18 14:30:41 +00002858 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2859 C->getLocation(),
2860 TU)))
2861 return true;
2862 }
2863
2864 // Visit parameters and return type, if present.
2865 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2866 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2867 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2868 // Visit the whole type.
2869 if (Visit(TL))
2870 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002871 } else if (FunctionProtoTypeLoc Proto =
2872 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002873 if (E->hasExplicitParameters()) {
2874 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002875 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2876 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002877 return true;
2878 } else {
2879 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002880 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002881 return true;
2882 }
2883 }
2884 }
2885 break;
2886 }
2887
2888 case VisitorJob::PostChildrenVisitKind:
2889 if (PostChildrenVisitor(Parent, ClientData))
2890 return true;
2891 break;
2892 }
2893 }
2894 return false;
2895}
2896
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002897bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002898 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002899 if (!WorkListFreeList.empty()) {
2900 WL = WorkListFreeList.back();
2901 WL->clear();
2902 WorkListFreeList.pop_back();
2903 }
2904 else {
2905 WL = new VisitorWorkList();
2906 WorkListCache.push_back(WL);
2907 }
2908 EnqueueWorkList(*WL, S);
2909 bool result = RunVisitorWorkList(*WL);
2910 WorkListFreeList.push_back(WL);
2911 return result;
2912}
2913
2914namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002915typedef SmallVector<SourceRange, 4> RefNamePieces;
James Y Knight04ec5bf2015-12-24 02:59:37 +00002916RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2917 const DeclarationNameInfo &NI, SourceRange QLoc,
2918 const SourceRange *TemplateArgsLoc = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002919 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2920 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2921 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2922
2923 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2924
2925 RefNamePieces Pieces;
2926
2927 if (WantQualifier && QLoc.isValid())
2928 Pieces.push_back(QLoc);
2929
2930 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2931 Pieces.push_back(NI.getLoc());
James Y Knight04ec5bf2015-12-24 02:59:37 +00002932
2933 if (WantTemplateArgs && TemplateArgsLoc && TemplateArgsLoc->isValid())
2934 Pieces.push_back(*TemplateArgsLoc);
2935
Guy Benyei11169dd2012-12-18 14:30:41 +00002936 if (Kind == DeclarationName::CXXOperatorName) {
2937 Pieces.push_back(SourceLocation::getFromRawEncoding(
2938 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2939 Pieces.push_back(SourceLocation::getFromRawEncoding(
2940 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2941 }
2942
2943 if (WantSinglePiece) {
2944 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2945 Pieces.clear();
2946 Pieces.push_back(R);
2947 }
2948
2949 return Pieces;
2950}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002951}
Guy Benyei11169dd2012-12-18 14:30:41 +00002952
2953//===----------------------------------------------------------------------===//
2954// Misc. API hooks.
2955//===----------------------------------------------------------------------===//
2956
Chad Rosier05c71aa2013-03-27 18:28:23 +00002957static void fatal_error_handler(void *user_data, const std::string& reason,
2958 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002959 // Write the result out to stderr avoiding errs() because raw_ostreams can
2960 // call report_fatal_error.
2961 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2962 ::abort();
2963}
2964
Chandler Carruth66660742014-06-27 16:37:27 +00002965namespace {
2966struct RegisterFatalErrorHandler {
2967 RegisterFatalErrorHandler() {
2968 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2969 }
2970};
2971}
2972
2973static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
2974
Guy Benyei11169dd2012-12-18 14:30:41 +00002975extern "C" {
2976CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2977 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002978 // We use crash recovery to make some of our APIs more reliable, implicitly
2979 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002980 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2981 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002982
Chandler Carruth66660742014-06-27 16:37:27 +00002983 // Look through the managed static to trigger construction of the managed
2984 // static which registers our fatal error handler. This ensures it is only
2985 // registered once.
2986 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00002987
Adrian Prantlbc068582015-07-08 01:00:30 +00002988 // Initialize targets for clang module support.
2989 llvm::InitializeAllTargets();
2990 llvm::InitializeAllTargetMCs();
2991 llvm::InitializeAllAsmPrinters();
2992 llvm::InitializeAllAsmParsers();
2993
Adrian Prantlfb2398d2015-07-17 01:19:54 +00002994 CIndexer *CIdxr = new CIndexer();
2995
Guy Benyei11169dd2012-12-18 14:30:41 +00002996 if (excludeDeclarationsFromPCH)
2997 CIdxr->setOnlyLocalDecls();
2998 if (displayDiagnostics)
2999 CIdxr->setDisplayDiagnostics();
3000
3001 if (getenv("LIBCLANG_BGPRIO_INDEX"))
3002 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
3003 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
3004 if (getenv("LIBCLANG_BGPRIO_EDIT"))
3005 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
3006 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
3007
3008 return CIdxr;
3009}
3010
3011void clang_disposeIndex(CXIndex CIdx) {
3012 if (CIdx)
3013 delete static_cast<CIndexer *>(CIdx);
3014}
3015
3016void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
3017 if (CIdx)
3018 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
3019}
3020
3021unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
3022 if (CIdx)
3023 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
3024 return 0;
3025}
3026
3027void clang_toggleCrashRecovery(unsigned isEnabled) {
3028 if (isEnabled)
3029 llvm::CrashRecoveryContext::Enable();
3030 else
3031 llvm::CrashRecoveryContext::Disable();
3032}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003033
Guy Benyei11169dd2012-12-18 14:30:41 +00003034CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
3035 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003036 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003037 enum CXErrorCode Result =
3038 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00003039 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003040 assert((TU && Result == CXError_Success) ||
3041 (!TU && Result != CXError_Success));
3042 return TU;
3043}
3044
3045enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
3046 const char *ast_filename,
3047 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003048 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00003049 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003050
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003051 if (!CIdx || !ast_filename || !out_TU)
3052 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00003053
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00003054 LOG_FUNC_SECTION {
3055 *Log << ast_filename;
3056 }
3057
Guy Benyei11169dd2012-12-18 14:30:41 +00003058 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3059 FileSystemOptions FileSystemOpts;
3060
Justin Bognerd512c1e2014-10-15 00:33:06 +00003061 IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
3062 CompilerInstance::createDiagnostics(new DiagnosticOptions());
David Blaikie6f7382d2014-08-10 19:08:04 +00003063 std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
Adrian Prantlfb2398d2015-07-17 01:19:54 +00003064 ast_filename, CXXIdx->getPCHContainerOperations()->getRawReader(), Diags,
Adrian Prantl6b21ab22015-08-27 19:46:20 +00003065 FileSystemOpts, /*UseDebugInfo=*/false,
3066 CXXIdx->getOnlyLocalDecls(), None,
David Blaikie6f7382d2014-08-10 19:08:04 +00003067 /*CaptureDiagnostics=*/true,
3068 /*AllowPCHWithCompilerErrors=*/true,
3069 /*UserFilesAreVolatile=*/true);
3070 *out_TU = MakeCXTranslationUnit(CXXIdx, AU.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003071 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003072}
3073
3074unsigned clang_defaultEditingTranslationUnitOptions() {
3075 return CXTranslationUnit_PrecompiledPreamble |
3076 CXTranslationUnit_CacheCompletionResults;
3077}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003078
Guy Benyei11169dd2012-12-18 14:30:41 +00003079CXTranslationUnit
3080clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
3081 const char *source_filename,
3082 int num_command_line_args,
3083 const char * const *command_line_args,
3084 unsigned num_unsaved_files,
3085 struct CXUnsavedFile *unsaved_files) {
3086 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
3087 return clang_parseTranslationUnit(CIdx, source_filename,
3088 command_line_args, num_command_line_args,
3089 unsaved_files, num_unsaved_files,
3090 Options);
3091}
3092
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003093static CXErrorCode
3094clang_parseTranslationUnit_Impl(CXIndex CIdx, const char *source_filename,
3095 const char *const *command_line_args,
3096 int num_command_line_args,
3097 ArrayRef<CXUnsavedFile> unsaved_files,
3098 unsigned options, CXTranslationUnit *out_TU) {
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003099 // Set up the initial return values.
3100 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00003101 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003102
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003103 // Check arguments.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003104 if (!CIdx || !out_TU)
3105 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003106
Guy Benyei11169dd2012-12-18 14:30:41 +00003107 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3108
3109 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3110 setThreadBackgroundPriority();
3111
3112 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
Benjamin Kramer5c248d82015-12-15 09:30:31 +00003113 bool CreatePreambleOnFirstParse =
3114 options & CXTranslationUnit_CreatePreambleOnFirstParse;
Guy Benyei11169dd2012-12-18 14:30:41 +00003115 // FIXME: Add a flag for modules.
3116 TranslationUnitKind TUKind
3117 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00003118 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00003119 = options & CXTranslationUnit_CacheCompletionResults;
3120 bool IncludeBriefCommentsInCodeCompletion
3121 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
3122 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
3123 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
3124
3125 // Configure the diagnostics.
3126 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00003127 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00003128
3129 // Recover resources if we crash before exiting this function.
3130 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
3131 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00003132 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00003133
Ahmed Charlesb8984322014-03-07 20:03:18 +00003134 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3135 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003136
3137 // Recover resources if we crash before exiting this function.
3138 llvm::CrashRecoveryContextCleanupRegistrar<
3139 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3140
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003141 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003142 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003143 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003144 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003145 }
3146
Ahmed Charlesb8984322014-03-07 20:03:18 +00003147 std::unique_ptr<std::vector<const char *>> Args(
3148 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003149
3150 // Recover resources if we crash before exiting this method.
3151 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
3152 ArgsCleanup(Args.get());
3153
3154 // Since the Clang C library is primarily used by batch tools dealing with
3155 // (often very broken) source code, where spell-checking can have a
3156 // significant negative impact on performance (particularly when
3157 // precompiled headers are involved), we disable it by default.
3158 // Only do this if we haven't found a spell-checking-related argument.
3159 bool FoundSpellCheckingArgument = false;
3160 for (int I = 0; I != num_command_line_args; ++I) {
3161 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
3162 strcmp(command_line_args[I], "-fspell-checking") == 0) {
3163 FoundSpellCheckingArgument = true;
3164 break;
3165 }
3166 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003167 Args->insert(Args->end(), command_line_args,
3168 command_line_args + num_command_line_args);
3169
Benjamin Kramerc02670e2015-11-18 16:14:27 +00003170 if (!FoundSpellCheckingArgument)
3171 Args->insert(Args->begin() + 1, "-fno-spell-checking");
3172
Guy Benyei11169dd2012-12-18 14:30:41 +00003173 // The 'source_filename' argument is optional. If the caller does not
3174 // specify it then it is assumed that the source file is specified
3175 // in the actual argument list.
3176 // Put the source file after command_line_args otherwise if '-x' flag is
3177 // present it will be unused.
3178 if (source_filename)
3179 Args->push_back(source_filename);
3180
3181 // Do we need the detailed preprocessing record?
3182 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
3183 Args->push_back("-Xclang");
3184 Args->push_back("-detailed-preprocessing-record");
3185 }
3186
3187 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00003188 std::unique_ptr<ASTUnit> ErrUnit;
Benjamin Kramer5c248d82015-12-15 09:30:31 +00003189 // Unless the user specified that they want the preamble on the first parse
3190 // set it up to be created on the first reparse. This makes the first parse
3191 // faster, trading for a slower (first) reparse.
3192 unsigned PrecompilePreambleAfterNParses =
3193 !PrecompilePreamble ? 0 : 2 - CreatePreambleOnFirstParse;
Ahmed Charlesb8984322014-03-07 20:03:18 +00003194 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003195 Args->data(), Args->data() + Args->size(),
3196 CXXIdx->getPCHContainerOperations(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00003197 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
3198 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
Benjamin Kramer5c248d82015-12-15 09:30:31 +00003199 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreambleAfterNParses,
3200 TUKind, CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
Ahmed Charlesb8984322014-03-07 20:03:18 +00003201 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
Argyrios Kyrtzidisa3e2ff12015-11-20 03:36:21 +00003202 /*UserFilesAreVolatile=*/true, ForSerialization,
3203 CXXIdx->getPCHContainerOperations()->getRawReader().getFormat(),
3204 &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00003205
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003206 // Early failures in LoadFromCommandLine may return with ErrUnit unset.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003207 if (!Unit && !ErrUnit)
3208 return CXError_ASTReadError;
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003209
Guy Benyei11169dd2012-12-18 14:30:41 +00003210 if (NumErrors != Diags->getClient()->getNumErrors()) {
3211 // Make sure to check that 'Unit' is non-NULL.
3212 if (CXXIdx->getDisplayDiagnostics())
3213 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
3214 }
3215
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003216 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get()))
3217 return CXError_ASTReadError;
3218
3219 *out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
3220 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003221}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003222
3223CXTranslationUnit
3224clang_parseTranslationUnit(CXIndex CIdx,
3225 const char *source_filename,
3226 const char *const *command_line_args,
3227 int num_command_line_args,
3228 struct CXUnsavedFile *unsaved_files,
3229 unsigned num_unsaved_files,
3230 unsigned options) {
3231 CXTranslationUnit TU;
3232 enum CXErrorCode Result = clang_parseTranslationUnit2(
3233 CIdx, source_filename, command_line_args, num_command_line_args,
3234 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00003235 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003236 assert((TU && Result == CXError_Success) ||
3237 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003238 return TU;
3239}
3240
3241enum CXErrorCode clang_parseTranslationUnit2(
Benjamin Kramerc02670e2015-11-18 16:14:27 +00003242 CXIndex CIdx, const char *source_filename,
3243 const char *const *command_line_args, int num_command_line_args,
3244 struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
3245 unsigned options, CXTranslationUnit *out_TU) {
3246 SmallVector<const char *, 4> Args;
3247 Args.push_back("clang");
3248 Args.append(command_line_args, command_line_args + num_command_line_args);
3249 return clang_parseTranslationUnit2FullArgv(
3250 CIdx, source_filename, Args.data(), Args.size(), unsaved_files,
3251 num_unsaved_files, options, out_TU);
3252}
3253
3254enum CXErrorCode clang_parseTranslationUnit2FullArgv(
3255 CXIndex CIdx, const char *source_filename,
3256 const char *const *command_line_args, int num_command_line_args,
3257 struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
3258 unsigned options, CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003259 LOG_FUNC_SECTION {
3260 *Log << source_filename << ": ";
3261 for (int i = 0; i != num_command_line_args; ++i)
3262 *Log << command_line_args[i] << " ";
3263 }
3264
Alp Toker9d85b182014-07-07 01:23:14 +00003265 if (num_unsaved_files && !unsaved_files)
3266 return CXError_InvalidArguments;
3267
Alp Toker5c532982014-07-07 22:42:03 +00003268 CXErrorCode result = CXError_Failure;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003269 auto ParseTranslationUnitImpl = [=, &result] {
3270 result = clang_parseTranslationUnit_Impl(
3271 CIdx, source_filename, command_line_args, num_command_line_args,
3272 llvm::makeArrayRef(unsaved_files, num_unsaved_files), options, out_TU);
3273 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003274 llvm::CrashRecoveryContext CRC;
3275
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003276 if (!RunSafely(CRC, ParseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003277 fprintf(stderr, "libclang: crash detected during parsing: {\n");
3278 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3279 fprintf(stderr, " 'command_line_args' : [");
3280 for (int i = 0; i != num_command_line_args; ++i) {
3281 if (i)
3282 fprintf(stderr, ", ");
3283 fprintf(stderr, "'%s'", command_line_args[i]);
3284 }
3285 fprintf(stderr, "],\n");
3286 fprintf(stderr, " 'unsaved_files' : [");
3287 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3288 if (i)
3289 fprintf(stderr, ", ");
3290 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3291 unsaved_files[i].Length);
3292 }
3293 fprintf(stderr, "],\n");
3294 fprintf(stderr, " 'options' : %d,\n", options);
3295 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003296
3297 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003298 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003299 if (CXTranslationUnit *TU = out_TU)
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003300 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003301 }
Alp Toker5c532982014-07-07 22:42:03 +00003302
3303 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003304}
3305
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003306CXString clang_Type_getObjCEncoding(CXType CT) {
3307 CXTranslationUnit tu = static_cast<CXTranslationUnit>(CT.data[1]);
3308 ASTContext &Ctx = getASTUnit(tu)->getASTContext();
3309 std::string encoding;
3310 Ctx.getObjCEncodingForType(QualType::getFromOpaquePtr(CT.data[0]),
3311 encoding);
3312
3313 return cxstring::createDup(encoding);
3314}
3315
3316static const IdentifierInfo *getMacroIdentifier(CXCursor C) {
3317 if (C.kind == CXCursor_MacroDefinition) {
3318 if (const MacroDefinitionRecord *MDR = getCursorMacroDefinition(C))
3319 return MDR->getName();
3320 } else if (C.kind == CXCursor_MacroExpansion) {
3321 MacroExpansionCursor ME = getCursorMacroExpansion(C);
3322 return ME.getName();
3323 }
3324 return nullptr;
3325}
3326
3327unsigned clang_Cursor_isMacroFunctionLike(CXCursor C) {
3328 const IdentifierInfo *II = getMacroIdentifier(C);
3329 if (!II) {
3330 return false;
3331 }
3332 ASTUnit *ASTU = getCursorASTUnit(C);
3333 Preprocessor &PP = ASTU->getPreprocessor();
3334 if (const MacroInfo *MI = PP.getMacroInfo(II))
3335 return MI->isFunctionLike();
3336 return false;
3337}
3338
3339unsigned clang_Cursor_isMacroBuiltin(CXCursor C) {
3340 const IdentifierInfo *II = getMacroIdentifier(C);
3341 if (!II) {
3342 return false;
3343 }
3344 ASTUnit *ASTU = getCursorASTUnit(C);
3345 Preprocessor &PP = ASTU->getPreprocessor();
3346 if (const MacroInfo *MI = PP.getMacroInfo(II))
3347 return MI->isBuiltinMacro();
3348 return false;
3349}
3350
3351unsigned clang_Cursor_isFunctionInlined(CXCursor C) {
3352 const Decl *D = getCursorDecl(C);
3353 const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D);
3354 if (!FD) {
3355 return false;
3356 }
3357 return FD->isInlined();
3358}
3359
3360static StringLiteral* getCFSTR_value(CallExpr *callExpr) {
3361 if (callExpr->getNumArgs() != 1) {
3362 return nullptr;
3363 }
3364
3365 StringLiteral *S = nullptr;
3366 auto *arg = callExpr->getArg(0);
3367 if (arg->getStmtClass() == Stmt::ImplicitCastExprClass) {
3368 ImplicitCastExpr *I = static_cast<ImplicitCastExpr *>(arg);
3369 auto *subExpr = I->getSubExprAsWritten();
3370
3371 if(subExpr->getStmtClass() != Stmt::StringLiteralClass){
3372 return nullptr;
3373 }
3374
3375 S = static_cast<StringLiteral *>(I->getSubExprAsWritten());
3376 } else if (arg->getStmtClass() == Stmt::StringLiteralClass) {
3377 S = static_cast<StringLiteral *>(callExpr->getArg(0));
3378 } else {
3379 return nullptr;
3380 }
3381 return S;
3382}
3383
3384typedef struct {
3385 CXEvalResultKind EvalType;
3386 union {
3387 int intVal;
3388 double floatVal;
3389 char *stringVal;
3390 } EvalData;
3391} ExprEvalResult;
3392
3393void clang_EvalResult_dispose(CXEvalResult E) {
3394 ExprEvalResult *ER = (ExprEvalResult *)E;
3395 if (ER) {
3396 CXEvalResultKind evalType = ER->EvalType;
3397
3398 if (evalType != CXEval_UnExposed && evalType != CXEval_Float &&
3399 evalType != CXEval_Int && ER->EvalData.stringVal) {
3400 free((void *) ER->EvalData.stringVal);
3401 }
3402 free((void *)ER);
3403 }
3404}
3405
3406CXEvalResultKind clang_EvalResult_getKind(CXEvalResult E) {
3407 if (!E) {
3408 return CXEval_UnExposed;
3409 }
3410 return ((ExprEvalResult *)E)->EvalType;
3411}
3412
3413int clang_EvalResult_getAsInt(CXEvalResult E) {
3414 if (!E) {
3415 return 0;
3416 }
3417 return ((ExprEvalResult *)E)->EvalData.intVal;
3418}
3419
3420double clang_EvalResult_getAsDouble(CXEvalResult E) {
3421 if (!E) {
3422 return 0;
3423 }
3424 return ((ExprEvalResult *)E)->EvalData.floatVal;
3425}
3426
3427const char* clang_EvalResult_getAsStr(CXEvalResult E) {
3428 if (!E) {
3429 return nullptr;
3430 }
3431 return ((ExprEvalResult *)E)->EvalData.stringVal;
3432}
3433
3434static const ExprEvalResult* evaluateExpr(Expr *expr, CXCursor C) {
3435 Expr::EvalResult ER;
3436 ASTContext &ctx = getCursorContext(C);
3437 if (!expr) {
3438 return nullptr;
3439 }
3440 expr = expr->IgnoreParens();
3441 bool res = expr->EvaluateAsRValue(ER, ctx);
3442 QualType rettype;
3443 CallExpr *callExpr;
3444 ExprEvalResult *result = (ExprEvalResult *) malloc(sizeof(ExprEvalResult));
3445 if (!result) {
3446 return nullptr;
3447 }
3448 result->EvalType = CXEval_UnExposed;
3449
3450 if (res) {
3451
3452 if (ER.Val.isInt()) {
3453 result->EvalType = CXEval_Int;
3454 result->EvalData.intVal = ER.Val.getInt().getExtValue();
3455 return result;
3456 } else if (ER.Val.isFloat()) {
3457
3458 llvm::SmallVector<char, 100> Buffer;
3459 ER.Val.getFloat().toString(Buffer);
3460 std::string floatStr(Buffer.data(), Buffer.size());
3461 result->EvalType = CXEval_Float;
3462 bool ignored;
3463 llvm::APFloat apFloat = ER.Val.getFloat();
3464 apFloat.convert(llvm::APFloat::IEEEdouble,
3465 llvm::APFloat::rmNearestTiesToEven, &ignored);
3466 result->EvalData.floatVal = apFloat.convertToDouble();
3467 return result;
3468
3469 } else if (expr->getStmtClass() == Stmt::ImplicitCastExprClass) {
3470
3471 const ImplicitCastExpr *I = dyn_cast<ImplicitCastExpr>(expr);
3472 auto *subExpr = I->getSubExprAsWritten();
3473 if (subExpr->getStmtClass() == Stmt::StringLiteralClass ||
3474 subExpr->getStmtClass() == Stmt::ObjCStringLiteralClass) {
3475
3476 const StringLiteral *StrE = nullptr;
3477 const ObjCStringLiteral *ObjCExpr;
3478 ObjCExpr = dyn_cast<ObjCStringLiteral>(subExpr);
3479
3480 if (ObjCExpr) {
3481 StrE = ObjCExpr->getString();
3482 result->EvalType = CXEval_ObjCStrLiteral;
3483 } else {
3484 StrE = cast<StringLiteral>(I->getSubExprAsWritten());
3485 result->EvalType = CXEval_StrLiteral;
3486 }
3487
3488 std::string strRef(StrE->getString().str());
3489 result->EvalData.stringVal = (char *)malloc(strRef.size()+1);
3490 strncpy((char*)result->EvalData.stringVal, strRef.c_str(),
3491 strRef.size());
3492 result->EvalData.stringVal[strRef.size()] = '\0';
3493 return result;
3494 }
3495
3496 } else if (expr->getStmtClass() == Stmt::ObjCStringLiteralClass ||
3497 expr->getStmtClass() == Stmt::StringLiteralClass) {
3498
3499 const StringLiteral *StrE = nullptr;
3500 const ObjCStringLiteral *ObjCExpr;
3501 ObjCExpr = dyn_cast<ObjCStringLiteral>(expr);
3502
3503 if (ObjCExpr) {
3504 StrE = ObjCExpr->getString();
3505 result->EvalType = CXEval_ObjCStrLiteral;
3506 } else {
3507 StrE = cast<StringLiteral>(expr);
3508 result->EvalType = CXEval_StrLiteral;
3509 }
3510
3511 std::string strRef(StrE->getString().str());
3512 result->EvalData.stringVal = (char *)malloc(strRef.size()+1);
3513 strncpy((char*)result->EvalData.stringVal, strRef.c_str(),
3514 strRef.size());
3515 result->EvalData.stringVal[strRef.size()] = '\0';
3516 return result;
3517
3518 } else if (expr->getStmtClass() == Stmt::CStyleCastExprClass) {
3519
3520 CStyleCastExpr *CC = static_cast<CStyleCastExpr *>(expr);
3521
3522 rettype = CC->getType();
3523 if (rettype.getAsString() == "CFStringRef" &&
3524 CC->getSubExpr()->getStmtClass() == Stmt::CallExprClass) {
3525
3526 callExpr = static_cast<CallExpr *>(CC->getSubExpr());
3527 StringLiteral* S = getCFSTR_value(callExpr);
3528 if (S) {
3529 std::string strLiteral(S->getString().str());
3530 result->EvalType = CXEval_CFStr;
3531
3532 result->EvalData.stringVal = (char *)malloc(strLiteral.size()+1);
3533 strncpy((char*)result->EvalData.stringVal, strLiteral.c_str(),
3534 strLiteral.size());
3535 result->EvalData.stringVal[strLiteral.size()] = '\0';
3536 return result;
3537 }
3538 }
3539
3540 } else if (expr->getStmtClass() == Stmt::CallExprClass) {
3541
3542 callExpr = static_cast<CallExpr *>(expr);
3543 rettype = callExpr->getCallReturnType(ctx);
3544
3545 if (rettype->isVectorType() || callExpr->getNumArgs() > 1) {
3546 return nullptr;
3547 }
3548 if (rettype->isIntegralType(ctx) || rettype->isRealFloatingType()) {
3549 if(callExpr->getNumArgs() == 1 &&
3550 !callExpr->getArg(0)->getType()->isIntegralType(ctx)){
3551
3552 return nullptr;
3553 }
3554 } else if(rettype.getAsString() == "CFStringRef") {
3555
3556 StringLiteral* S = getCFSTR_value(callExpr);
3557 if (S) {
3558 std::string strLiteral(S->getString().str());
3559 result->EvalType = CXEval_CFStr;
3560 result->EvalData.stringVal = (char *)malloc(strLiteral.size()+1);
3561 strncpy((char*)result->EvalData.stringVal, strLiteral.c_str(),
3562 strLiteral.size());
3563 result->EvalData.stringVal[strLiteral.size()] = '\0';
3564 return result;
3565 }
3566 }
3567
3568 } else if (expr->getStmtClass() == Stmt::DeclRefExprClass) {
3569
3570 DeclRefExpr *D = static_cast<DeclRefExpr *>(expr);
3571 ValueDecl *V = D->getDecl();
3572 if (V->getKind() == Decl::Function) {
3573 std::string strName(V->getNameAsString());
3574 result->EvalType = CXEval_Other;
3575 result->EvalData.stringVal = (char *)malloc(strName.size()+1);
3576 strncpy((char*)result->EvalData.stringVal, strName.c_str(),
3577 strName.size());
3578 result->EvalData.stringVal[strName.size()] = '\0';
3579 return result;
3580 }
3581 }
3582
3583 }
3584
3585 clang_EvalResult_dispose((CXEvalResult *)result);
3586 return nullptr;
3587}
3588
3589CXEvalResult clang_Cursor_Evaluate(CXCursor C) {
3590 const Decl *D = getCursorDecl(C);
3591 if (D) {
3592 const Expr *expr = nullptr;
3593 if (auto *Var = dyn_cast<VarDecl>(D)) {
3594 expr = Var->getInit();
3595 } else if (auto *Field = dyn_cast<FieldDecl>(D)) {
3596 expr = Field->getInClassInitializer();
3597 }
3598 if (expr)
Aaron Ballman01dc1572016-01-20 15:25:30 +00003599 return const_cast<CXEvalResult>(reinterpret_cast<const void *>(
3600 evaluateExpr(const_cast<Expr *>(expr), C)));
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003601 return nullptr;
3602 }
3603
3604 const CompoundStmt *compoundStmt = dyn_cast_or_null<CompoundStmt>(getCursorStmt(C));
3605 if (compoundStmt) {
3606 Expr *expr = nullptr;
3607 for (auto *bodyIterator : compoundStmt->body()) {
3608 if ((expr = dyn_cast<Expr>(bodyIterator))) {
3609 break;
3610 }
3611 }
3612 if (expr)
Aaron Ballman01dc1572016-01-20 15:25:30 +00003613 return const_cast<CXEvalResult>(
3614 reinterpret_cast<const void *>(evaluateExpr(expr, C)));
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003615 }
3616 return nullptr;
3617}
3618
3619unsigned clang_Cursor_hasAttrs(CXCursor C) {
3620 const Decl *D = getCursorDecl(C);
3621 if (!D) {
3622 return 0;
3623 }
3624
3625 if (D->hasAttrs()) {
3626 return 1;
3627 }
3628
3629 return 0;
3630}
Guy Benyei11169dd2012-12-18 14:30:41 +00003631unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
3632 return CXSaveTranslationUnit_None;
3633}
3634
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003635static CXSaveError clang_saveTranslationUnit_Impl(CXTranslationUnit TU,
3636 const char *FileName,
3637 unsigned options) {
3638 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003639 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3640 setThreadBackgroundPriority();
3641
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003642 bool hadError = cxtu::getASTUnit(TU)->Save(FileName);
3643 return hadError ? CXSaveError_Unknown : CXSaveError_None;
Guy Benyei11169dd2012-12-18 14:30:41 +00003644}
3645
3646int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3647 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003648 LOG_FUNC_SECTION {
3649 *Log << TU << ' ' << FileName;
3650 }
3651
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003652 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003653 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003654 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003655 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003656
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003657 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003658 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3659 if (!CXXUnit->hasSema())
3660 return CXSaveError_InvalidTU;
3661
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003662 CXSaveError result;
3663 auto SaveTranslationUnitImpl = [=, &result]() {
3664 result = clang_saveTranslationUnit_Impl(TU, FileName, options);
3665 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003666
3667 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3668 getenv("LIBCLANG_NOTHREADS")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003669 SaveTranslationUnitImpl();
Guy Benyei11169dd2012-12-18 14:30:41 +00003670
3671 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3672 PrintLibclangResourceUsage(TU);
3673
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003674 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003675 }
3676
3677 // We have an AST that has invalid nodes due to compiler errors.
3678 // Use a crash recovery thread for protection.
3679
3680 llvm::CrashRecoveryContext CRC;
3681
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003682 if (!RunSafely(CRC, SaveTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003683 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3684 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3685 fprintf(stderr, " 'options' : %d,\n", options);
3686 fprintf(stderr, "}\n");
3687
3688 return CXSaveError_Unknown;
3689
3690 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3691 PrintLibclangResourceUsage(TU);
3692 }
3693
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003694 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003695}
3696
3697void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3698 if (CTUnit) {
3699 // If the translation unit has been marked as unsafe to free, just discard
3700 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003701 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3702 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003703 return;
3704
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003705 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003706 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003707 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3708 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003709 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003710 delete CTUnit;
3711 }
3712}
3713
3714unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3715 return CXReparse_None;
3716}
3717
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003718static CXErrorCode
3719clang_reparseTranslationUnit_Impl(CXTranslationUnit TU,
3720 ArrayRef<CXUnsavedFile> unsaved_files,
3721 unsigned options) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003722 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003723 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003724 LOG_BAD_TU(TU);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003725 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003726 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003727
3728 // Reset the associated diagnostics.
3729 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003730 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003731
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003732 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003733 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3734 setThreadBackgroundPriority();
3735
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003736 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003737 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003738
3739 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3740 new std::vector<ASTUnit::RemappedFile>());
3741
Guy Benyei11169dd2012-12-18 14:30:41 +00003742 // Recover resources if we crash before exiting this function.
3743 llvm::CrashRecoveryContextCleanupRegistrar<
3744 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003745
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003746 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003747 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003748 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003749 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003750 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003751
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003752 if (!CXXUnit->Reparse(CXXIdx->getPCHContainerOperations(),
3753 *RemappedFiles.get()))
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003754 return CXError_Success;
3755 if (isASTReadError(CXXUnit))
3756 return CXError_ASTReadError;
3757 return CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003758}
3759
3760int clang_reparseTranslationUnit(CXTranslationUnit TU,
3761 unsigned num_unsaved_files,
3762 struct CXUnsavedFile *unsaved_files,
3763 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003764 LOG_FUNC_SECTION {
3765 *Log << TU;
3766 }
3767
Alp Toker9d85b182014-07-07 01:23:14 +00003768 if (num_unsaved_files && !unsaved_files)
3769 return CXError_InvalidArguments;
3770
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003771 CXErrorCode result;
3772 auto ReparseTranslationUnitImpl = [=, &result]() {
3773 result = clang_reparseTranslationUnit_Impl(
3774 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options);
3775 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003776
3777 if (getenv("LIBCLANG_NOTHREADS")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003778 ReparseTranslationUnitImpl();
Alp Toker5c532982014-07-07 22:42:03 +00003779 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003780 }
3781
3782 llvm::CrashRecoveryContext CRC;
3783
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003784 if (!RunSafely(CRC, ReparseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003785 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003786 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003787 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003788 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3789 PrintLibclangResourceUsage(TU);
3790
Alp Toker5c532982014-07-07 22:42:03 +00003791 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003792}
3793
3794
3795CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003796 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003797 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003798 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003799 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003800
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003801 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003802 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003803}
3804
3805CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003806 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003807 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003808 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003809 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003810
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003811 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003812 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3813}
3814
3815} // end: extern "C"
3816
3817//===----------------------------------------------------------------------===//
3818// CXFile Operations.
3819//===----------------------------------------------------------------------===//
3820
3821extern "C" {
3822CXString clang_getFileName(CXFile SFile) {
3823 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003824 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003825
3826 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003827 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003828}
3829
3830time_t clang_getFileTime(CXFile SFile) {
3831 if (!SFile)
3832 return 0;
3833
3834 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3835 return FEnt->getModificationTime();
3836}
3837
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003838CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003839 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003840 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003841 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003842 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003843
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003844 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003845
3846 FileManager &FMgr = CXXUnit->getFileManager();
3847 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3848}
3849
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003850unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3851 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003852 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003853 LOG_BAD_TU(TU);
3854 return 0;
3855 }
3856
3857 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003858 return 0;
3859
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003860 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003861 FileEntry *FEnt = static_cast<FileEntry *>(file);
3862 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3863 .isFileMultipleIncludeGuarded(FEnt);
3864}
3865
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003866int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3867 if (!file || !outID)
3868 return 1;
3869
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003870 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003871 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3872 outID->data[0] = ID.getDevice();
3873 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003874 outID->data[2] = FEnt->getModificationTime();
3875 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003876}
3877
Argyrios Kyrtzidisac3997e2014-08-16 00:26:19 +00003878int clang_File_isEqual(CXFile file1, CXFile file2) {
3879 if (file1 == file2)
3880 return true;
3881
3882 if (!file1 || !file2)
3883 return false;
3884
3885 FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
3886 FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
3887 return FEnt1->getUniqueID() == FEnt2->getUniqueID();
3888}
3889
Guy Benyei11169dd2012-12-18 14:30:41 +00003890} // end: extern "C"
3891
3892//===----------------------------------------------------------------------===//
3893// CXCursor Operations.
3894//===----------------------------------------------------------------------===//
3895
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003896static const Decl *getDeclFromExpr(const Stmt *E) {
3897 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003898 return getDeclFromExpr(CE->getSubExpr());
3899
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003900 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003901 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003902 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003903 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003904 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003905 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003906 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003907 if (PRE->isExplicitProperty())
3908 return PRE->getExplicitProperty();
3909 // It could be messaging both getter and setter as in:
3910 // ++myobj.myprop;
3911 // in which case prefer to associate the setter since it is less obvious
3912 // from inspecting the source that the setter is going to get called.
3913 if (PRE->isMessagingSetter())
3914 return PRE->getImplicitPropertySetter();
3915 return PRE->getImplicitPropertyGetter();
3916 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003917 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003918 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003919 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003920 if (Expr *Src = OVE->getSourceExpr())
3921 return getDeclFromExpr(Src);
3922
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003923 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003924 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003925 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003926 if (!CE->isElidable())
3927 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003928 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003929 return OME->getMethodDecl();
3930
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003931 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003932 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003933 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003934 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3935 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003936 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003937 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3938 isa<ParmVarDecl>(SizeOfPack->getPack()))
3939 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003940
3941 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003942}
3943
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003944static SourceLocation getLocationFromExpr(const Expr *E) {
3945 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003946 return getLocationFromExpr(CE->getSubExpr());
3947
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003948 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003949 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003950 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003951 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003952 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003953 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003954 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003955 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003956 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003957 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003958 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003959 return PropRef->getLocation();
3960
3961 return E->getLocStart();
3962}
3963
Aaron Ballmana85d3f82015-11-12 15:25:06 +00003964static std::string getMangledStructor(std::unique_ptr<MangleContext> &M,
3965 std::unique_ptr<llvm::DataLayout> &DL,
3966 const NamedDecl *ND,
3967 unsigned StructorType) {
3968 std::string FrontendBuf;
3969 llvm::raw_string_ostream FOS(FrontendBuf);
3970
3971 if (const auto *CD = dyn_cast_or_null<CXXConstructorDecl>(ND))
3972 M->mangleCXXCtor(CD, static_cast<CXXCtorType>(StructorType), FOS);
3973 else if (const auto *DD = dyn_cast_or_null<CXXDestructorDecl>(ND))
3974 M->mangleCXXDtor(DD, static_cast<CXXDtorType>(StructorType), FOS);
3975
3976 std::string BackendBuf;
3977 llvm::raw_string_ostream BOS(BackendBuf);
3978
3979 llvm::Mangler::getNameWithPrefix(BOS, llvm::Twine(FOS.str()), *DL);
3980
3981 return BOS.str();
3982}
3983
Guy Benyei11169dd2012-12-18 14:30:41 +00003984extern "C" {
3985
3986unsigned clang_visitChildren(CXCursor parent,
3987 CXCursorVisitor visitor,
3988 CXClientData client_data) {
3989 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3990 /*VisitPreprocessorLast=*/false);
3991 return CursorVis.VisitChildren(parent);
3992}
3993
3994#ifndef __has_feature
3995#define __has_feature(x) 0
3996#endif
3997#if __has_feature(blocks)
3998typedef enum CXChildVisitResult
3999 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
4000
4001static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
4002 CXClientData client_data) {
4003 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
4004 return block(cursor, parent);
4005}
4006#else
4007// If we are compiled with a compiler that doesn't have native blocks support,
4008// define and call the block manually, so the
4009typedef struct _CXChildVisitResult
4010{
4011 void *isa;
4012 int flags;
4013 int reserved;
4014 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
4015 CXCursor);
4016} *CXCursorVisitorBlock;
4017
4018static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
4019 CXClientData client_data) {
4020 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
4021 return block->invoke(block, cursor, parent);
4022}
4023#endif
4024
4025
4026unsigned clang_visitChildrenWithBlock(CXCursor parent,
4027 CXCursorVisitorBlock block) {
4028 return clang_visitChildren(parent, visitWithBlock, block);
4029}
4030
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004031static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004032 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004033 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004034
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004035 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004036 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004037 if (const ObjCPropertyImplDecl *PropImpl =
4038 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004039 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004040 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004041
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004042 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004043 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004044 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004045
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004046 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004047 }
4048
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004049 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004050 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004051
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004052 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00004053 // No, this isn't the same as the code below. getIdentifier() is non-virtual
4054 // and returns different names. NamedDecl returns the class name and
4055 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004056 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004057
4058 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004059 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004060
4061 SmallString<1024> S;
4062 llvm::raw_svector_ostream os(S);
4063 ND->printName(os);
4064
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004065 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004066}
4067
4068CXString clang_getCursorSpelling(CXCursor C) {
4069 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00004070 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004071
4072 if (clang_isReference(C.kind)) {
4073 switch (C.kind) {
4074 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004075 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004076 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004077 }
4078 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004079 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004080 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004081 }
4082 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004083 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004084 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004085 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004086 }
4087 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004088 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004089 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004090 }
4091 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004092 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004093 assert(Type && "Missing type decl");
4094
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004095 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00004096 getAsString());
4097 }
4098 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004099 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004100 assert(Template && "Missing template decl");
4101
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004102 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004103 }
4104
4105 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004106 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004107 assert(NS && "Missing namespace decl");
4108
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004109 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004110 }
4111
4112 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004113 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004114 assert(Field && "Missing member decl");
4115
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004116 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004117 }
4118
4119 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004120 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004121 assert(Label && "Missing label");
4122
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004123 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004124 }
4125
4126 case CXCursor_OverloadedDeclRef: {
4127 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004128 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
4129 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004130 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004131 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004132 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004133 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004134 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004135 OverloadedTemplateStorage *Ovl
4136 = Storage.get<OverloadedTemplateStorage*>();
4137 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004138 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004139 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004140 }
4141
4142 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004143 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004144 assert(Var && "Missing variable decl");
4145
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004146 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004147 }
4148
4149 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004150 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00004151 }
4152 }
4153
4154 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00004155 const Expr *E = getCursorExpr(C);
4156
4157 if (C.kind == CXCursor_ObjCStringLiteral ||
4158 C.kind == CXCursor_StringLiteral) {
4159 const StringLiteral *SLit;
4160 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
4161 SLit = OSL->getString();
4162 } else {
4163 SLit = cast<StringLiteral>(E);
4164 }
4165 SmallString<256> Buf;
4166 llvm::raw_svector_ostream OS(Buf);
4167 SLit->outputString(OS);
4168 return cxstring::createDup(OS.str());
4169 }
4170
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004171 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004172 if (D)
4173 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004174 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004175 }
4176
4177 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004178 const Stmt *S = getCursorStmt(C);
4179 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004180 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004181
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004182 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004183 }
4184
4185 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004186 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00004187 ->getNameStart());
4188
4189 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004190 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00004191 ->getNameStart());
4192
4193 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004194 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004195
4196 if (clang_isDeclaration(C.kind))
4197 return getDeclSpelling(getCursorDecl(C));
4198
4199 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00004200 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004201 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00004202 }
4203
4204 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00004205 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004206 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00004207 }
4208
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004209 if (C.kind == CXCursor_PackedAttr) {
4210 return cxstring::createRef("packed");
4211 }
4212
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00004213 if (C.kind == CXCursor_VisibilityAttr) {
4214 const VisibilityAttr *AA = cast<VisibilityAttr>(cxcursor::getCursorAttr(C));
4215 switch (AA->getVisibility()) {
4216 case VisibilityAttr::VisibilityType::Default:
4217 return cxstring::createRef("default");
4218 case VisibilityAttr::VisibilityType::Hidden:
4219 return cxstring::createRef("hidden");
4220 case VisibilityAttr::VisibilityType::Protected:
4221 return cxstring::createRef("protected");
4222 }
4223 llvm_unreachable("unknown visibility type");
4224 }
4225
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004226 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004227}
4228
4229CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
4230 unsigned pieceIndex,
4231 unsigned options) {
4232 if (clang_Cursor_isNull(C))
4233 return clang_getNullRange();
4234
4235 ASTContext &Ctx = getCursorContext(C);
4236
4237 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004238 const Stmt *S = getCursorStmt(C);
4239 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004240 if (pieceIndex > 0)
4241 return clang_getNullRange();
4242 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
4243 }
4244
4245 return clang_getNullRange();
4246 }
4247
4248 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004249 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00004250 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
4251 if (pieceIndex >= ME->getNumSelectorLocs())
4252 return clang_getNullRange();
4253 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
4254 }
4255 }
4256
4257 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
4258 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004259 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00004260 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
4261 if (pieceIndex >= MD->getNumSelectorLocs())
4262 return clang_getNullRange();
4263 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
4264 }
4265 }
4266
4267 if (C.kind == CXCursor_ObjCCategoryDecl ||
4268 C.kind == CXCursor_ObjCCategoryImplDecl) {
4269 if (pieceIndex > 0)
4270 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004271 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00004272 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
4273 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004274 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00004275 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
4276 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
4277 }
4278
4279 if (C.kind == CXCursor_ModuleImportDecl) {
4280 if (pieceIndex > 0)
4281 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004282 if (const ImportDecl *ImportD =
4283 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004284 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
4285 if (!Locs.empty())
4286 return cxloc::translateSourceRange(Ctx,
4287 SourceRange(Locs.front(), Locs.back()));
4288 }
4289 return clang_getNullRange();
4290 }
4291
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00004292 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
4293 C.kind == CXCursor_ConversionFunction) {
4294 if (pieceIndex > 0)
4295 return clang_getNullRange();
4296 if (const FunctionDecl *FD =
4297 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
4298 DeclarationNameInfo FunctionName = FD->getNameInfo();
4299 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
4300 }
4301 return clang_getNullRange();
4302 }
4303
Guy Benyei11169dd2012-12-18 14:30:41 +00004304 // FIXME: A CXCursor_InclusionDirective should give the location of the
4305 // filename, but we don't keep track of this.
4306
4307 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
4308 // but we don't keep track of this.
4309
4310 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
4311 // but we don't keep track of this.
4312
4313 // Default handling, give the location of the cursor.
4314
4315 if (pieceIndex > 0)
4316 return clang_getNullRange();
4317
4318 CXSourceLocation CXLoc = clang_getCursorLocation(C);
4319 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
4320 return cxloc::translateSourceRange(Ctx, Loc);
4321}
4322
Eli Bendersky44a206f2014-07-31 18:04:56 +00004323CXString clang_Cursor_getMangling(CXCursor C) {
4324 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
4325 return cxstring::createEmpty();
4326
Eli Bendersky44a206f2014-07-31 18:04:56 +00004327 // Mangling only works for functions and variables.
Eli Bendersky79759592014-08-01 15:01:10 +00004328 const Decl *D = getCursorDecl(C);
Eli Bendersky44a206f2014-07-31 18:04:56 +00004329 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
4330 return cxstring::createEmpty();
4331
Eli Bendersky79759592014-08-01 15:01:10 +00004332 // First apply frontend mangling.
Eli Bendersky44a206f2014-07-31 18:04:56 +00004333 const NamedDecl *ND = cast<NamedDecl>(D);
Eli Bendersky79759592014-08-01 15:01:10 +00004334 ASTContext &Ctx = ND->getASTContext();
4335 std::unique_ptr<MangleContext> MC(Ctx.createMangleContext());
Eli Bendersky44a206f2014-07-31 18:04:56 +00004336
Eli Bendersky79759592014-08-01 15:01:10 +00004337 std::string FrontendBuf;
4338 llvm::raw_string_ostream FrontendBufOS(FrontendBuf);
Ehsan Akhgarif8d44de2015-10-08 00:01:20 +00004339 if (MC->shouldMangleDeclName(ND)) {
4340 MC->mangleName(ND, FrontendBufOS);
4341 } else {
4342 ND->printName(FrontendBufOS);
4343 }
Eli Bendersky44a206f2014-07-31 18:04:56 +00004344
Eli Bendersky79759592014-08-01 15:01:10 +00004345 // Now apply backend mangling.
4346 std::unique_ptr<llvm::DataLayout> DL(
Eric Christopher964a5f32015-08-05 23:48:05 +00004347 new llvm::DataLayout(Ctx.getTargetInfo().getDataLayoutString()));
Eli Bendersky79759592014-08-01 15:01:10 +00004348
4349 std::string FinalBuf;
4350 llvm::raw_string_ostream FinalBufOS(FinalBuf);
Rafael Espindolab633d202015-06-23 13:59:36 +00004351 llvm::Mangler::getNameWithPrefix(FinalBufOS, llvm::Twine(FrontendBufOS.str()),
4352 *DL);
Eli Bendersky79759592014-08-01 15:01:10 +00004353
4354 return cxstring::createDup(FinalBufOS.str());
Eli Bendersky44a206f2014-07-31 18:04:56 +00004355}
4356
Saleem Abdulrasool60034432015-11-12 03:57:22 +00004357CXStringSet *clang_Cursor_getCXXManglings(CXCursor C) {
4358 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
4359 return nullptr;
4360
4361 const Decl *D = getCursorDecl(C);
4362 if (!(isa<CXXRecordDecl>(D) || isa<CXXMethodDecl>(D)))
4363 return nullptr;
4364
4365 const NamedDecl *ND = cast<NamedDecl>(D);
4366
4367 ASTContext &Ctx = ND->getASTContext();
4368 std::unique_ptr<MangleContext> M(Ctx.createMangleContext());
4369 std::unique_ptr<llvm::DataLayout> DL(
4370 new llvm::DataLayout(Ctx.getTargetInfo().getDataLayoutString()));
4371
4372 std::vector<std::string> Manglings;
4373
4374 auto hasDefaultCXXMethodCC = [](ASTContext &C, const CXXMethodDecl *MD) {
4375 auto DefaultCC = C.getDefaultCallingConvention(/*IsVariadic=*/false,
4376 /*IsCSSMethod=*/true);
4377 auto CC = MD->getType()->getAs<FunctionProtoType>()->getCallConv();
4378 return CC == DefaultCC;
4379 };
4380
4381 if (const auto *CD = dyn_cast_or_null<CXXConstructorDecl>(ND)) {
4382 Manglings.emplace_back(getMangledStructor(M, DL, CD, Ctor_Base));
4383
4384 if (Ctx.getTargetInfo().getCXXABI().isItaniumFamily())
4385 if (!CD->getParent()->isAbstract())
4386 Manglings.emplace_back(getMangledStructor(M, DL, CD, Ctor_Complete));
4387
4388 if (Ctx.getTargetInfo().getCXXABI().isMicrosoft())
4389 if (CD->hasAttr<DLLExportAttr>() && CD->isDefaultConstructor())
4390 if (!(hasDefaultCXXMethodCC(Ctx, CD) && CD->getNumParams() == 0))
4391 Manglings.emplace_back(getMangledStructor(M, DL, CD,
4392 Ctor_DefaultClosure));
4393 } else if (const auto *DD = dyn_cast_or_null<CXXDestructorDecl>(ND)) {
4394 Manglings.emplace_back(getMangledStructor(M, DL, DD, Dtor_Base));
4395 if (Ctx.getTargetInfo().getCXXABI().isItaniumFamily()) {
4396 Manglings.emplace_back(getMangledStructor(M, DL, DD, Dtor_Complete));
Saleem Abdulrasoold5af8ae2015-12-10 06:30:23 +00004397 if (DD->isVirtual())
Saleem Abdulrasool60034432015-11-12 03:57:22 +00004398 Manglings.emplace_back(getMangledStructor(M, DL, DD, Dtor_Deleting));
4399 }
4400 }
4401
4402 return cxstring::createSet(Manglings);
4403}
4404
Guy Benyei11169dd2012-12-18 14:30:41 +00004405CXString clang_getCursorDisplayName(CXCursor C) {
4406 if (!clang_isDeclaration(C.kind))
4407 return clang_getCursorSpelling(C);
4408
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004409 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004410 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004411 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004412
4413 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004414 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004415 D = FunTmpl->getTemplatedDecl();
4416
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004417 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004418 SmallString<64> Str;
4419 llvm::raw_svector_ostream OS(Str);
4420 OS << *Function;
4421 if (Function->getPrimaryTemplate())
4422 OS << "<>";
4423 OS << "(";
4424 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
4425 if (I)
4426 OS << ", ";
4427 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
4428 }
4429
4430 if (Function->isVariadic()) {
4431 if (Function->getNumParams())
4432 OS << ", ";
4433 OS << "...";
4434 }
4435 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004436 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004437 }
4438
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004439 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004440 SmallString<64> Str;
4441 llvm::raw_svector_ostream OS(Str);
4442 OS << *ClassTemplate;
4443 OS << "<";
4444 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
4445 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
4446 if (I)
4447 OS << ", ";
4448
4449 NamedDecl *Param = Params->getParam(I);
4450 if (Param->getIdentifier()) {
4451 OS << Param->getIdentifier()->getName();
4452 continue;
4453 }
4454
4455 // There is no parameter name, which makes this tricky. Try to come up
4456 // with something useful that isn't too long.
4457 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
4458 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
4459 else if (NonTypeTemplateParmDecl *NTTP
4460 = dyn_cast<NonTypeTemplateParmDecl>(Param))
4461 OS << NTTP->getType().getAsString(Policy);
4462 else
4463 OS << "template<...> class";
4464 }
4465
4466 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004467 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004468 }
4469
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004470 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00004471 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
4472 // If the type was explicitly written, use that.
4473 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004474 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00004475
Benjamin Kramer9170e912013-02-22 15:46:01 +00004476 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00004477 llvm::raw_svector_ostream OS(Str);
4478 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00004479 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00004480 ClassSpec->getTemplateArgs().data(),
4481 ClassSpec->getTemplateArgs().size(),
4482 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004483 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004484 }
4485
4486 return clang_getCursorSpelling(C);
4487}
4488
4489CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
4490 switch (Kind) {
4491 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004492 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004493 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004494 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004495 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004496 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004497 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004498 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004499 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004500 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004501 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004502 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004503 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004504 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004505 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004506 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004507 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004508 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004509 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004510 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004511 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004512 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004513 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004514 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004515 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004516 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004517 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004518 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004519 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004520 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004521 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004522 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004523 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004524 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004525 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004526 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004527 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004528 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004529 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004530 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00004531 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004532 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004533 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004534 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004535 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004536 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004537 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004538 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004539 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004540 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004541 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004542 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004543 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004544 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004545 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004546 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004547 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004548 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004549 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004550 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004551 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004552 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004553 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004554 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004555 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004556 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004557 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004558 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004559 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004560 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004561 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004562 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004563 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004564 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004565 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004566 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004567 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004568 return cxstring::createRef("ArraySubscriptExpr");
Alexey Bataev1a3320e2015-08-25 14:24:04 +00004569 case CXCursor_OMPArraySectionExpr:
4570 return cxstring::createRef("OMPArraySectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004571 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004572 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004573 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004574 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004575 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004576 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004577 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004578 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004579 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004580 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004581 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004582 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004583 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004584 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004585 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004586 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004587 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004588 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004589 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004590 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004591 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004592 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004593 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004594 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004595 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004596 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004597 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004598 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004599 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004600 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004601 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004602 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004603 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004604 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004605 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004606 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004607 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004608 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004609 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004610 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004611 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004612 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004613 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004614 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004615 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004616 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004617 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004618 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004619 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004620 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00004621 case CXCursor_ObjCSelfExpr:
4622 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004623 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004624 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004625 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004626 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004627 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004628 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004629 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004630 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004631 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004632 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004633 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004634 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004635 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004636 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004637 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004638 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004639 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004640 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004641 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004642 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004643 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004644 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004645 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004646 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004647 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004648 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004649 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004650 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004651 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004652 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004653 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004654 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004655 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004656 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004657 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004658 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004659 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004660 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004661 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004662 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004663 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004664 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004665 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004666 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004667 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004668 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004669 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004670 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004671 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004672 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004673 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004674 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004675 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004676 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004677 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004678 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004679 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004680 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004681 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004682 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004683 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004684 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004685 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004686 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004687 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004688 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004689 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004690 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004691 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004692 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004693 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004694 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004695 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004696 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004697 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004698 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004699 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004700 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004701 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004702 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004703 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004704 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004705 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004706 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004707 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004708 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004709 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004710 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00004711 case CXCursor_SEHLeaveStmt:
4712 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004713 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004714 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004715 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004716 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00004717 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004718 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00004719 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004720 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00004721 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004722 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00004723 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004724 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00004725 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004726 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004727 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004728 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004729 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004730 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004731 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004732 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004733 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004734 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004735 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004736 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004737 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004738 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004739 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004740 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004741 case CXCursor_PackedAttr:
4742 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00004743 case CXCursor_PureAttr:
4744 return cxstring::createRef("attribute(pure)");
4745 case CXCursor_ConstAttr:
4746 return cxstring::createRef("attribute(const)");
4747 case CXCursor_NoDuplicateAttr:
4748 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00004749 case CXCursor_CUDAConstantAttr:
4750 return cxstring::createRef("attribute(constant)");
4751 case CXCursor_CUDADeviceAttr:
4752 return cxstring::createRef("attribute(device)");
4753 case CXCursor_CUDAGlobalAttr:
4754 return cxstring::createRef("attribute(global)");
4755 case CXCursor_CUDAHostAttr:
4756 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00004757 case CXCursor_CUDASharedAttr:
4758 return cxstring::createRef("attribute(shared)");
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00004759 case CXCursor_VisibilityAttr:
4760 return cxstring::createRef("attribute(visibility)");
Saleem Abdulrasool8aa0b802015-12-10 18:45:18 +00004761 case CXCursor_DLLExport:
4762 return cxstring::createRef("attribute(dllexport)");
4763 case CXCursor_DLLImport:
4764 return cxstring::createRef("attribute(dllimport)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004765 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004766 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004767 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004768 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00004769 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004770 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004771 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004772 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004773 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004774 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00004775 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004776 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00004777 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004778 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004779 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004780 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004781 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004782 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004783 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004784 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004785 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004786 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004787 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004788 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004789 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004790 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004791 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004792 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004793 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004794 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004795 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004796 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004797 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004798 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004799 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004800 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004801 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004802 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004803 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004804 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004805 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004806 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004807 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004808 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004809 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004810 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004811 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004812 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004813 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004814 return cxstring::createRef("OMPParallelDirective");
4815 case CXCursor_OMPSimdDirective:
4816 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004817 case CXCursor_OMPForDirective:
4818 return cxstring::createRef("OMPForDirective");
Alexander Musmanf82886e2014-09-18 05:12:34 +00004819 case CXCursor_OMPForSimdDirective:
4820 return cxstring::createRef("OMPForSimdDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004821 case CXCursor_OMPSectionsDirective:
4822 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004823 case CXCursor_OMPSectionDirective:
4824 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004825 case CXCursor_OMPSingleDirective:
4826 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004827 case CXCursor_OMPMasterDirective:
4828 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004829 case CXCursor_OMPCriticalDirective:
4830 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004831 case CXCursor_OMPParallelForDirective:
4832 return cxstring::createRef("OMPParallelForDirective");
Alexander Musmane4e893b2014-09-23 09:33:00 +00004833 case CXCursor_OMPParallelForSimdDirective:
4834 return cxstring::createRef("OMPParallelForSimdDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004835 case CXCursor_OMPParallelSectionsDirective:
4836 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004837 case CXCursor_OMPTaskDirective:
4838 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004839 case CXCursor_OMPTaskyieldDirective:
4840 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004841 case CXCursor_OMPBarrierDirective:
4842 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004843 case CXCursor_OMPTaskwaitDirective:
4844 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00004845 case CXCursor_OMPTaskgroupDirective:
4846 return cxstring::createRef("OMPTaskgroupDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00004847 case CXCursor_OMPFlushDirective:
4848 return cxstring::createRef("OMPFlushDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004849 case CXCursor_OMPOrderedDirective:
4850 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00004851 case CXCursor_OMPAtomicDirective:
4852 return cxstring::createRef("OMPAtomicDirective");
Alexey Bataev0bd520b2014-09-19 08:19:49 +00004853 case CXCursor_OMPTargetDirective:
4854 return cxstring::createRef("OMPTargetDirective");
Michael Wong65f367f2015-07-21 13:44:28 +00004855 case CXCursor_OMPTargetDataDirective:
4856 return cxstring::createRef("OMPTargetDataDirective");
Samuel Antaodf67fc42016-01-19 19:15:56 +00004857 case CXCursor_OMPTargetEnterDataDirective:
4858 return cxstring::createRef("OMPTargetEnterDataDirective");
Samuel Antao72590762016-01-19 20:04:50 +00004859 case CXCursor_OMPTargetExitDataDirective:
4860 return cxstring::createRef("OMPTargetExitDataDirective");
Alexey Bataev13314bf2014-10-09 04:18:56 +00004861 case CXCursor_OMPTeamsDirective:
4862 return cxstring::createRef("OMPTeamsDirective");
Alexey Bataev6d4ed052015-07-01 06:57:41 +00004863 case CXCursor_OMPCancellationPointDirective:
4864 return cxstring::createRef("OMPCancellationPointDirective");
Alexey Bataev80909872015-07-02 11:25:17 +00004865 case CXCursor_OMPCancelDirective:
4866 return cxstring::createRef("OMPCancelDirective");
Alexey Bataev49f6e782015-12-01 04:18:41 +00004867 case CXCursor_OMPTaskLoopDirective:
4868 return cxstring::createRef("OMPTaskLoopDirective");
Alexey Bataev0a6ed842015-12-03 09:40:15 +00004869 case CXCursor_OMPTaskLoopSimdDirective:
4870 return cxstring::createRef("OMPTaskLoopSimdDirective");
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00004871 case CXCursor_OMPDistributeDirective:
4872 return cxstring::createRef("OMPDistributeDirective");
Francisco Lopes da Silva975a9f62015-01-21 16:24:11 +00004873 case CXCursor_OverloadCandidate:
4874 return cxstring::createRef("OverloadCandidate");
Sergey Kalinichev8f3b1872015-11-15 13:48:32 +00004875 case CXCursor_TypeAliasTemplateDecl:
4876 return cxstring::createRef("TypeAliasTemplateDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004877 }
4878
4879 llvm_unreachable("Unhandled CXCursorKind");
4880}
4881
4882struct GetCursorData {
4883 SourceLocation TokenBeginLoc;
4884 bool PointsAtMacroArgExpansion;
4885 bool VisitedObjCPropertyImplDecl;
4886 SourceLocation VisitedDeclaratorDeclStartLoc;
4887 CXCursor &BestCursor;
4888
4889 GetCursorData(SourceManager &SM,
4890 SourceLocation tokenBegin, CXCursor &outputCursor)
4891 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4892 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4893 VisitedObjCPropertyImplDecl = false;
4894 }
4895};
4896
4897static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4898 CXCursor parent,
4899 CXClientData client_data) {
4900 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4901 CXCursor *BestCursor = &Data->BestCursor;
4902
4903 // If we point inside a macro argument we should provide info of what the
4904 // token is so use the actual cursor, don't replace it with a macro expansion
4905 // cursor.
4906 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4907 return CXChildVisit_Recurse;
4908
4909 if (clang_isDeclaration(cursor.kind)) {
4910 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004911 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004912 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4913 if (MD->isImplicit())
4914 return CXChildVisit_Break;
4915
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004916 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004917 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4918 // Check that when we have multiple @class references in the same line,
4919 // that later ones do not override the previous ones.
4920 // If we have:
4921 // @class Foo, Bar;
4922 // source ranges for both start at '@', so 'Bar' will end up overriding
4923 // 'Foo' even though the cursor location was at 'Foo'.
4924 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4925 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004926 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004927 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4928 if (PrevID != ID &&
4929 !PrevID->isThisDeclarationADefinition() &&
4930 !ID->isThisDeclarationADefinition())
4931 return CXChildVisit_Break;
4932 }
4933
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004934 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004935 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4936 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4937 // Check that when we have multiple declarators in the same line,
4938 // that later ones do not override the previous ones.
4939 // If we have:
4940 // int Foo, Bar;
4941 // source ranges for both start at 'int', so 'Bar' will end up overriding
4942 // 'Foo' even though the cursor location was at 'Foo'.
4943 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4944 return CXChildVisit_Break;
4945 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4946
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004947 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004948 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4949 (void)PropImp;
4950 // Check that when we have multiple @synthesize in the same line,
4951 // that later ones do not override the previous ones.
4952 // If we have:
4953 // @synthesize Foo, Bar;
4954 // source ranges for both start at '@', so 'Bar' will end up overriding
4955 // 'Foo' even though the cursor location was at 'Foo'.
4956 if (Data->VisitedObjCPropertyImplDecl)
4957 return CXChildVisit_Break;
4958 Data->VisitedObjCPropertyImplDecl = true;
4959 }
4960 }
4961
4962 if (clang_isExpression(cursor.kind) &&
4963 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004964 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004965 // Avoid having the cursor of an expression replace the declaration cursor
4966 // when the expression source range overlaps the declaration range.
4967 // This can happen for C++ constructor expressions whose range generally
4968 // include the variable declaration, e.g.:
4969 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4970 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4971 D->getLocation() == Data->TokenBeginLoc)
4972 return CXChildVisit_Break;
4973 }
4974 }
4975
4976 // If our current best cursor is the construction of a temporary object,
4977 // don't replace that cursor with a type reference, because we want
4978 // clang_getCursor() to point at the constructor.
4979 if (clang_isExpression(BestCursor->kind) &&
4980 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4981 cursor.kind == CXCursor_TypeRef) {
4982 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4983 // as having the actual point on the type reference.
4984 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4985 return CXChildVisit_Recurse;
4986 }
Douglas Gregore9d95f12015-07-07 03:57:35 +00004987
4988 // If we already have an Objective-C superclass reference, don't
4989 // update it further.
4990 if (BestCursor->kind == CXCursor_ObjCSuperClassRef)
4991 return CXChildVisit_Break;
4992
Guy Benyei11169dd2012-12-18 14:30:41 +00004993 *BestCursor = cursor;
4994 return CXChildVisit_Recurse;
4995}
4996
4997CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004998 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004999 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005000 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005001 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005002
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005003 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005004 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5005
5006 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
5007 CXCursor Result = cxcursor::getCursor(TU, SLoc);
5008
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005009 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00005010 CXFile SearchFile;
5011 unsigned SearchLine, SearchColumn;
5012 CXFile ResultFile;
5013 unsigned ResultLine, ResultColumn;
5014 CXString SearchFileName, ResultFileName, KindSpelling, USR;
5015 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
5016 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00005017
5018 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
5019 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005020 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00005021 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00005022 SearchFileName = clang_getFileName(SearchFile);
5023 ResultFileName = clang_getFileName(ResultFile);
5024 KindSpelling = clang_getCursorKindSpelling(Result.kind);
5025 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005026 *Log << llvm::format("(%s:%d:%d) = %s",
5027 clang_getCString(SearchFileName), SearchLine, SearchColumn,
5028 clang_getCString(KindSpelling))
5029 << llvm::format("(%s:%d:%d):%s%s",
5030 clang_getCString(ResultFileName), ResultLine, ResultColumn,
5031 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00005032 clang_disposeString(SearchFileName);
5033 clang_disposeString(ResultFileName);
5034 clang_disposeString(KindSpelling);
5035 clang_disposeString(USR);
5036
5037 CXCursor Definition = clang_getCursorDefinition(Result);
5038 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
5039 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
5040 CXString DefinitionKindSpelling
5041 = clang_getCursorKindSpelling(Definition.kind);
5042 CXFile DefinitionFile;
5043 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005044 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00005045 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00005046 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005047 *Log << llvm::format(" -> %s(%s:%d:%d)",
5048 clang_getCString(DefinitionKindSpelling),
5049 clang_getCString(DefinitionFileName),
5050 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00005051 clang_disposeString(DefinitionFileName);
5052 clang_disposeString(DefinitionKindSpelling);
5053 }
5054 }
5055
5056 return Result;
5057}
5058
5059CXCursor clang_getNullCursor(void) {
5060 return MakeCXCursorInvalid(CXCursor_InvalidFile);
5061}
5062
5063unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005064 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
5065 // can't set consistently. For example, when visiting a DeclStmt we will set
5066 // it but we don't set it on the result of clang_getCursorDefinition for
5067 // a reference of the same declaration.
5068 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
5069 // when visiting a DeclStmt currently, the AST should be enhanced to be able
5070 // to provide that kind of info.
5071 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00005072 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005073 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00005074 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005075
Guy Benyei11169dd2012-12-18 14:30:41 +00005076 return X == Y;
5077}
5078
5079unsigned clang_hashCursor(CXCursor C) {
5080 unsigned Index = 0;
5081 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
5082 Index = 1;
5083
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005084 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00005085 std::make_pair(C.kind, C.data[Index]));
5086}
5087
5088unsigned clang_isInvalid(enum CXCursorKind K) {
5089 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
5090}
5091
5092unsigned clang_isDeclaration(enum CXCursorKind K) {
5093 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
5094 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
5095}
5096
5097unsigned clang_isReference(enum CXCursorKind K) {
5098 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
5099}
5100
5101unsigned clang_isExpression(enum CXCursorKind K) {
5102 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
5103}
5104
5105unsigned clang_isStatement(enum CXCursorKind K) {
5106 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
5107}
5108
5109unsigned clang_isAttribute(enum CXCursorKind K) {
5110 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
5111}
5112
5113unsigned clang_isTranslationUnit(enum CXCursorKind K) {
5114 return K == CXCursor_TranslationUnit;
5115}
5116
5117unsigned clang_isPreprocessing(enum CXCursorKind K) {
5118 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
5119}
5120
5121unsigned clang_isUnexposed(enum CXCursorKind K) {
5122 switch (K) {
5123 case CXCursor_UnexposedDecl:
5124 case CXCursor_UnexposedExpr:
5125 case CXCursor_UnexposedStmt:
5126 case CXCursor_UnexposedAttr:
5127 return true;
5128 default:
5129 return false;
5130 }
5131}
5132
5133CXCursorKind clang_getCursorKind(CXCursor C) {
5134 return C.kind;
5135}
5136
5137CXSourceLocation clang_getCursorLocation(CXCursor C) {
5138 if (clang_isReference(C.kind)) {
5139 switch (C.kind) {
5140 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005141 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00005142 = getCursorObjCSuperClassRef(C);
5143 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5144 }
5145
5146 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005147 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00005148 = getCursorObjCProtocolRef(C);
5149 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5150 }
5151
5152 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005153 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00005154 = getCursorObjCClassRef(C);
5155 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5156 }
5157
5158 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005159 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005160 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5161 }
5162
5163 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005164 std::pair<const TemplateDecl *, SourceLocation> P =
5165 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005166 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5167 }
5168
5169 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005170 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005171 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5172 }
5173
5174 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005175 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005176 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5177 }
5178
5179 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005180 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005181 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5182 }
5183
5184 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005185 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005186 if (!BaseSpec)
5187 return clang_getNullLocation();
5188
5189 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
5190 return cxloc::translateSourceLocation(getCursorContext(C),
5191 TSInfo->getTypeLoc().getBeginLoc());
5192
5193 return cxloc::translateSourceLocation(getCursorContext(C),
5194 BaseSpec->getLocStart());
5195 }
5196
5197 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005198 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005199 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
5200 }
5201
5202 case CXCursor_OverloadedDeclRef:
5203 return cxloc::translateSourceLocation(getCursorContext(C),
5204 getCursorOverloadedDeclRef(C).second);
5205
5206 default:
5207 // FIXME: Need a way to enumerate all non-reference cases.
5208 llvm_unreachable("Missed a reference kind");
5209 }
5210 }
5211
5212 if (clang_isExpression(C.kind))
5213 return cxloc::translateSourceLocation(getCursorContext(C),
5214 getLocationFromExpr(getCursorExpr(C)));
5215
5216 if (clang_isStatement(C.kind))
5217 return cxloc::translateSourceLocation(getCursorContext(C),
5218 getCursorStmt(C)->getLocStart());
5219
5220 if (C.kind == CXCursor_PreprocessingDirective) {
5221 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
5222 return cxloc::translateSourceLocation(getCursorContext(C), L);
5223 }
5224
5225 if (C.kind == CXCursor_MacroExpansion) {
5226 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005227 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00005228 return cxloc::translateSourceLocation(getCursorContext(C), L);
5229 }
5230
5231 if (C.kind == CXCursor_MacroDefinition) {
5232 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
5233 return cxloc::translateSourceLocation(getCursorContext(C), L);
5234 }
5235
5236 if (C.kind == CXCursor_InclusionDirective) {
5237 SourceLocation L
5238 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
5239 return cxloc::translateSourceLocation(getCursorContext(C), L);
5240 }
5241
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00005242 if (clang_isAttribute(C.kind)) {
5243 SourceLocation L
5244 = cxcursor::getCursorAttr(C)->getLocation();
5245 return cxloc::translateSourceLocation(getCursorContext(C), L);
5246 }
5247
Guy Benyei11169dd2012-12-18 14:30:41 +00005248 if (!clang_isDeclaration(C.kind))
5249 return clang_getNullLocation();
5250
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005251 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005252 if (!D)
5253 return clang_getNullLocation();
5254
5255 SourceLocation Loc = D->getLocation();
5256 // FIXME: Multiple variables declared in a single declaration
5257 // currently lack the information needed to correctly determine their
5258 // ranges when accounting for the type-specifier. We use context
5259 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
5260 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005261 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005262 if (!cxcursor::isFirstInDeclGroup(C))
5263 Loc = VD->getLocation();
5264 }
5265
5266 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005267 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005268 Loc = MD->getSelectorStartLoc();
5269
5270 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
5271}
5272
5273} // end extern "C"
5274
5275CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
5276 assert(TU);
5277
5278 // Guard against an invalid SourceLocation, or we may assert in one
5279 // of the following calls.
5280 if (SLoc.isInvalid())
5281 return clang_getNullCursor();
5282
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005283 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005284
5285 // Translate the given source location to make it point at the beginning of
5286 // the token under the cursor.
5287 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
5288 CXXUnit->getASTContext().getLangOpts());
5289
5290 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
5291 if (SLoc.isValid()) {
5292 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
5293 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
5294 /*VisitPreprocessorLast=*/true,
5295 /*VisitIncludedEntities=*/false,
5296 SourceLocation(SLoc));
5297 CursorVis.visitFileRegion();
5298 }
5299
5300 return Result;
5301}
5302
5303static SourceRange getRawCursorExtent(CXCursor C) {
5304 if (clang_isReference(C.kind)) {
5305 switch (C.kind) {
5306 case CXCursor_ObjCSuperClassRef:
5307 return getCursorObjCSuperClassRef(C).second;
5308
5309 case CXCursor_ObjCProtocolRef:
5310 return getCursorObjCProtocolRef(C).second;
5311
5312 case CXCursor_ObjCClassRef:
5313 return getCursorObjCClassRef(C).second;
5314
5315 case CXCursor_TypeRef:
5316 return getCursorTypeRef(C).second;
5317
5318 case CXCursor_TemplateRef:
5319 return getCursorTemplateRef(C).second;
5320
5321 case CXCursor_NamespaceRef:
5322 return getCursorNamespaceRef(C).second;
5323
5324 case CXCursor_MemberRef:
5325 return getCursorMemberRef(C).second;
5326
5327 case CXCursor_CXXBaseSpecifier:
5328 return getCursorCXXBaseSpecifier(C)->getSourceRange();
5329
5330 case CXCursor_LabelRef:
5331 return getCursorLabelRef(C).second;
5332
5333 case CXCursor_OverloadedDeclRef:
5334 return getCursorOverloadedDeclRef(C).second;
5335
5336 case CXCursor_VariableRef:
5337 return getCursorVariableRef(C).second;
5338
5339 default:
5340 // FIXME: Need a way to enumerate all non-reference cases.
5341 llvm_unreachable("Missed a reference kind");
5342 }
5343 }
5344
5345 if (clang_isExpression(C.kind))
5346 return getCursorExpr(C)->getSourceRange();
5347
5348 if (clang_isStatement(C.kind))
5349 return getCursorStmt(C)->getSourceRange();
5350
5351 if (clang_isAttribute(C.kind))
5352 return getCursorAttr(C)->getRange();
5353
5354 if (C.kind == CXCursor_PreprocessingDirective)
5355 return cxcursor::getCursorPreprocessingDirective(C);
5356
5357 if (C.kind == CXCursor_MacroExpansion) {
5358 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005359 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005360 return TU->mapRangeFromPreamble(Range);
5361 }
5362
5363 if (C.kind == CXCursor_MacroDefinition) {
5364 ASTUnit *TU = getCursorASTUnit(C);
5365 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
5366 return TU->mapRangeFromPreamble(Range);
5367 }
5368
5369 if (C.kind == CXCursor_InclusionDirective) {
5370 ASTUnit *TU = getCursorASTUnit(C);
5371 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
5372 return TU->mapRangeFromPreamble(Range);
5373 }
5374
5375 if (C.kind == CXCursor_TranslationUnit) {
5376 ASTUnit *TU = getCursorASTUnit(C);
5377 FileID MainID = TU->getSourceManager().getMainFileID();
5378 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
5379 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
5380 return SourceRange(Start, End);
5381 }
5382
5383 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005384 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005385 if (!D)
5386 return SourceRange();
5387
5388 SourceRange R = D->getSourceRange();
5389 // FIXME: Multiple variables declared in a single declaration
5390 // currently lack the information needed to correctly determine their
5391 // ranges when accounting for the type-specifier. We use context
5392 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
5393 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005394 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005395 if (!cxcursor::isFirstInDeclGroup(C))
5396 R.setBegin(VD->getLocation());
5397 }
5398 return R;
5399 }
5400 return SourceRange();
5401}
5402
5403/// \brief Retrieves the "raw" cursor extent, which is then extended to include
5404/// the decl-specifier-seq for declarations.
5405static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
5406 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005407 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005408 if (!D)
5409 return SourceRange();
5410
5411 SourceRange R = D->getSourceRange();
5412
5413 // Adjust the start of the location for declarations preceded by
5414 // declaration specifiers.
5415 SourceLocation StartLoc;
5416 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
5417 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
5418 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005419 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005420 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
5421 StartLoc = TI->getTypeLoc().getLocStart();
5422 }
5423
5424 if (StartLoc.isValid() && R.getBegin().isValid() &&
5425 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
5426 R.setBegin(StartLoc);
5427
5428 // FIXME: Multiple variables declared in a single declaration
5429 // currently lack the information needed to correctly determine their
5430 // ranges when accounting for the type-specifier. We use context
5431 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
5432 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005433 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005434 if (!cxcursor::isFirstInDeclGroup(C))
5435 R.setBegin(VD->getLocation());
5436 }
5437
5438 return R;
5439 }
5440
5441 return getRawCursorExtent(C);
5442}
5443
5444extern "C" {
5445
5446CXSourceRange clang_getCursorExtent(CXCursor C) {
5447 SourceRange R = getRawCursorExtent(C);
5448 if (R.isInvalid())
5449 return clang_getNullRange();
5450
5451 return cxloc::translateSourceRange(getCursorContext(C), R);
5452}
5453
5454CXCursor clang_getCursorReferenced(CXCursor C) {
5455 if (clang_isInvalid(C.kind))
5456 return clang_getNullCursor();
5457
5458 CXTranslationUnit tu = getCursorTU(C);
5459 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005460 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005461 if (!D)
5462 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005463 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005464 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005465 if (const ObjCPropertyImplDecl *PropImpl =
5466 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005467 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
5468 return MakeCXCursor(Property, tu);
5469
5470 return C;
5471 }
5472
5473 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005474 const Expr *E = getCursorExpr(C);
5475 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00005476 if (D) {
5477 CXCursor declCursor = MakeCXCursor(D, tu);
5478 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
5479 declCursor);
5480 return declCursor;
5481 }
5482
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005483 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00005484 return MakeCursorOverloadedDeclRef(Ovl, tu);
5485
5486 return clang_getNullCursor();
5487 }
5488
5489 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005490 const Stmt *S = getCursorStmt(C);
5491 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00005492 if (LabelDecl *label = Goto->getLabel())
5493 if (LabelStmt *labelS = label->getStmt())
5494 return MakeCXCursor(labelS, getCursorDecl(C), tu);
5495
5496 return clang_getNullCursor();
5497 }
Richard Smith66a81862015-05-04 02:25:31 +00005498
Guy Benyei11169dd2012-12-18 14:30:41 +00005499 if (C.kind == CXCursor_MacroExpansion) {
Richard Smith66a81862015-05-04 02:25:31 +00005500 if (const MacroDefinitionRecord *Def =
5501 getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005502 return MakeMacroDefinitionCursor(Def, tu);
5503 }
5504
5505 if (!clang_isReference(C.kind))
5506 return clang_getNullCursor();
5507
5508 switch (C.kind) {
5509 case CXCursor_ObjCSuperClassRef:
5510 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
5511
5512 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005513 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
5514 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005515 return MakeCXCursor(Def, tu);
5516
5517 return MakeCXCursor(Prot, tu);
5518 }
5519
5520 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005521 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
5522 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005523 return MakeCXCursor(Def, tu);
5524
5525 return MakeCXCursor(Class, tu);
5526 }
5527
5528 case CXCursor_TypeRef:
5529 return MakeCXCursor(getCursorTypeRef(C).first, tu );
5530
5531 case CXCursor_TemplateRef:
5532 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
5533
5534 case CXCursor_NamespaceRef:
5535 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
5536
5537 case CXCursor_MemberRef:
5538 return MakeCXCursor(getCursorMemberRef(C).first, tu );
5539
5540 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005541 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005542 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
5543 tu ));
5544 }
5545
5546 case CXCursor_LabelRef:
5547 // FIXME: We end up faking the "parent" declaration here because we
5548 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005549 return MakeCXCursor(getCursorLabelRef(C).first,
5550 cxtu::getASTUnit(tu)->getASTContext()
5551 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00005552 tu);
5553
5554 case CXCursor_OverloadedDeclRef:
5555 return C;
5556
5557 case CXCursor_VariableRef:
5558 return MakeCXCursor(getCursorVariableRef(C).first, tu);
5559
5560 default:
5561 // We would prefer to enumerate all non-reference cursor kinds here.
5562 llvm_unreachable("Unhandled reference cursor kind");
5563 }
5564}
5565
5566CXCursor clang_getCursorDefinition(CXCursor C) {
5567 if (clang_isInvalid(C.kind))
5568 return clang_getNullCursor();
5569
5570 CXTranslationUnit TU = getCursorTU(C);
5571
5572 bool WasReference = false;
5573 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
5574 C = clang_getCursorReferenced(C);
5575 WasReference = true;
5576 }
5577
5578 if (C.kind == CXCursor_MacroExpansion)
5579 return clang_getCursorReferenced(C);
5580
5581 if (!clang_isDeclaration(C.kind))
5582 return clang_getNullCursor();
5583
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005584 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005585 if (!D)
5586 return clang_getNullCursor();
5587
5588 switch (D->getKind()) {
5589 // Declaration kinds that don't really separate the notions of
5590 // declaration and definition.
5591 case Decl::Namespace:
5592 case Decl::Typedef:
5593 case Decl::TypeAlias:
5594 case Decl::TypeAliasTemplate:
5595 case Decl::TemplateTypeParm:
5596 case Decl::EnumConstant:
5597 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00005598 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005599 case Decl::IndirectField:
5600 case Decl::ObjCIvar:
5601 case Decl::ObjCAtDefsField:
5602 case Decl::ImplicitParam:
5603 case Decl::ParmVar:
5604 case Decl::NonTypeTemplateParm:
5605 case Decl::TemplateTemplateParm:
5606 case Decl::ObjCCategoryImpl:
5607 case Decl::ObjCImplementation:
5608 case Decl::AccessSpec:
5609 case Decl::LinkageSpec:
5610 case Decl::ObjCPropertyImpl:
5611 case Decl::FileScopeAsm:
5612 case Decl::StaticAssert:
5613 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00005614 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00005615 case Decl::Label: // FIXME: Is this right??
5616 case Decl::ClassScopeFunctionSpecialization:
5617 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00005618 case Decl::OMPThreadPrivate:
Douglas Gregor85f3f952015-07-07 03:57:15 +00005619 case Decl::ObjCTypeParam:
David Majnemerd9b1a4f2015-11-04 03:40:30 +00005620 case Decl::BuiltinTemplate:
Guy Benyei11169dd2012-12-18 14:30:41 +00005621 return C;
5622
5623 // Declaration kinds that don't make any sense here, but are
5624 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00005625 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005626 case Decl::TranslationUnit:
Richard Smithf19e1272015-03-07 00:04:49 +00005627 case Decl::ExternCContext:
Guy Benyei11169dd2012-12-18 14:30:41 +00005628 break;
5629
5630 // Declaration kinds for which the definition is not resolvable.
5631 case Decl::UnresolvedUsingTypename:
5632 case Decl::UnresolvedUsingValue:
5633 break;
5634
5635 case Decl::UsingDirective:
5636 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
5637 TU);
5638
5639 case Decl::NamespaceAlias:
5640 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
5641
5642 case Decl::Enum:
5643 case Decl::Record:
5644 case Decl::CXXRecord:
5645 case Decl::ClassTemplateSpecialization:
5646 case Decl::ClassTemplatePartialSpecialization:
5647 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
5648 return MakeCXCursor(Def, TU);
5649 return clang_getNullCursor();
5650
5651 case Decl::Function:
5652 case Decl::CXXMethod:
5653 case Decl::CXXConstructor:
5654 case Decl::CXXDestructor:
5655 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00005656 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005657 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00005658 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005659 return clang_getNullCursor();
5660 }
5661
Larisse Voufo39a1e502013-08-06 01:03:05 +00005662 case Decl::Var:
5663 case Decl::VarTemplateSpecialization:
5664 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00005665 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005666 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005667 return MakeCXCursor(Def, TU);
5668 return clang_getNullCursor();
5669 }
5670
5671 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00005672 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005673 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
5674 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
5675 return clang_getNullCursor();
5676 }
5677
5678 case Decl::ClassTemplate: {
5679 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
5680 ->getDefinition())
5681 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
5682 TU);
5683 return clang_getNullCursor();
5684 }
5685
Larisse Voufo39a1e502013-08-06 01:03:05 +00005686 case Decl::VarTemplate: {
5687 if (VarDecl *Def =
5688 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
5689 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
5690 return clang_getNullCursor();
5691 }
5692
Guy Benyei11169dd2012-12-18 14:30:41 +00005693 case Decl::Using:
5694 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
5695 D->getLocation(), TU);
5696
5697 case Decl::UsingShadow:
5698 return clang_getCursorDefinition(
5699 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
5700 TU));
5701
5702 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005703 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005704 if (Method->isThisDeclarationADefinition())
5705 return C;
5706
5707 // Dig out the method definition in the associated
5708 // @implementation, if we have it.
5709 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005710 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005711 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
5712 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
5713 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
5714 Method->isInstanceMethod()))
5715 if (Def->isThisDeclarationADefinition())
5716 return MakeCXCursor(Def, TU);
5717
5718 return clang_getNullCursor();
5719 }
5720
5721 case Decl::ObjCCategory:
5722 if (ObjCCategoryImplDecl *Impl
5723 = cast<ObjCCategoryDecl>(D)->getImplementation())
5724 return MakeCXCursor(Impl, TU);
5725 return clang_getNullCursor();
5726
5727 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005728 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005729 return MakeCXCursor(Def, TU);
5730 return clang_getNullCursor();
5731
5732 case Decl::ObjCInterface: {
5733 // There are two notions of a "definition" for an Objective-C
5734 // class: the interface and its implementation. When we resolved a
5735 // reference to an Objective-C class, produce the @interface as
5736 // the definition; when we were provided with the interface,
5737 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005738 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005739 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005740 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005741 return MakeCXCursor(Def, TU);
5742 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
5743 return MakeCXCursor(Impl, TU);
5744 return clang_getNullCursor();
5745 }
5746
5747 case Decl::ObjCProperty:
5748 // FIXME: We don't really know where to find the
5749 // ObjCPropertyImplDecls that implement this property.
5750 return clang_getNullCursor();
5751
5752 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005753 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005754 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005755 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005756 return MakeCXCursor(Def, TU);
5757
5758 return clang_getNullCursor();
5759
5760 case Decl::Friend:
5761 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
5762 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5763 return clang_getNullCursor();
5764
5765 case Decl::FriendTemplate:
5766 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
5767 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5768 return clang_getNullCursor();
5769 }
5770
5771 return clang_getNullCursor();
5772}
5773
5774unsigned clang_isCursorDefinition(CXCursor C) {
5775 if (!clang_isDeclaration(C.kind))
5776 return 0;
5777
5778 return clang_getCursorDefinition(C) == C;
5779}
5780
5781CXCursor clang_getCanonicalCursor(CXCursor C) {
5782 if (!clang_isDeclaration(C.kind))
5783 return C;
5784
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005785 if (const Decl *D = getCursorDecl(C)) {
5786 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005787 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5788 return MakeCXCursor(CatD, getCursorTU(C));
5789
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005790 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5791 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00005792 return MakeCXCursor(IFD, getCursorTU(C));
5793
5794 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5795 }
5796
5797 return C;
5798}
5799
5800int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5801 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5802}
5803
5804unsigned clang_getNumOverloadedDecls(CXCursor C) {
5805 if (C.kind != CXCursor_OverloadedDeclRef)
5806 return 0;
5807
5808 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005809 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005810 return E->getNumDecls();
5811
5812 if (OverloadedTemplateStorage *S
5813 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5814 return S->size();
5815
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005816 const Decl *D = Storage.get<const Decl *>();
5817 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005818 return Using->shadow_size();
5819
5820 return 0;
5821}
5822
5823CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5824 if (cursor.kind != CXCursor_OverloadedDeclRef)
5825 return clang_getNullCursor();
5826
5827 if (index >= clang_getNumOverloadedDecls(cursor))
5828 return clang_getNullCursor();
5829
5830 CXTranslationUnit TU = getCursorTU(cursor);
5831 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005832 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005833 return MakeCXCursor(E->decls_begin()[index], TU);
5834
5835 if (OverloadedTemplateStorage *S
5836 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5837 return MakeCXCursor(S->begin()[index], TU);
5838
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005839 const Decl *D = Storage.get<const Decl *>();
5840 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005841 // FIXME: This is, unfortunately, linear time.
5842 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5843 std::advance(Pos, index);
5844 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5845 }
5846
5847 return clang_getNullCursor();
5848}
5849
5850void clang_getDefinitionSpellingAndExtent(CXCursor C,
5851 const char **startBuf,
5852 const char **endBuf,
5853 unsigned *startLine,
5854 unsigned *startColumn,
5855 unsigned *endLine,
5856 unsigned *endColumn) {
5857 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005858 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005859 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5860
5861 SourceManager &SM = FD->getASTContext().getSourceManager();
5862 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5863 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5864 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5865 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5866 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5867 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5868}
5869
5870
5871CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5872 unsigned PieceIndex) {
5873 RefNamePieces Pieces;
5874
5875 switch (C.kind) {
5876 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005877 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005878 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5879 E->getQualifierLoc().getSourceRange());
5880 break;
5881
5882 case CXCursor_DeclRefExpr:
James Y Knight04ec5bf2015-12-24 02:59:37 +00005883 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C))) {
5884 SourceRange TemplateArgLoc(E->getLAngleLoc(), E->getRAngleLoc());
5885 Pieces =
5886 buildPieces(NameFlags, false, E->getNameInfo(),
5887 E->getQualifierLoc().getSourceRange(), &TemplateArgLoc);
5888 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005889 break;
5890
5891 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005892 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005893 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005894 const Expr *Callee = OCE->getCallee();
5895 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005896 Callee = ICE->getSubExpr();
5897
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005898 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005899 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5900 DRE->getQualifierLoc().getSourceRange());
5901 }
5902 break;
5903
5904 default:
5905 break;
5906 }
5907
5908 if (Pieces.empty()) {
5909 if (PieceIndex == 0)
5910 return clang_getCursorExtent(C);
5911 } else if (PieceIndex < Pieces.size()) {
5912 SourceRange R = Pieces[PieceIndex];
5913 if (R.isValid())
5914 return cxloc::translateSourceRange(getCursorContext(C), R);
5915 }
5916
5917 return clang_getNullRange();
5918}
5919
5920void clang_enableStackTraces(void) {
5921 llvm::sys::PrintStackTraceOnErrorSignal();
5922}
5923
5924void clang_executeOnThread(void (*fn)(void*), void *user_data,
5925 unsigned stack_size) {
5926 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5927}
5928
5929} // end: extern "C"
5930
5931//===----------------------------------------------------------------------===//
5932// Token-based Operations.
5933//===----------------------------------------------------------------------===//
5934
5935/* CXToken layout:
5936 * int_data[0]: a CXTokenKind
5937 * int_data[1]: starting token location
5938 * int_data[2]: token length
5939 * int_data[3]: reserved
5940 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5941 * otherwise unused.
5942 */
5943extern "C" {
5944
5945CXTokenKind clang_getTokenKind(CXToken CXTok) {
5946 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5947}
5948
5949CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5950 switch (clang_getTokenKind(CXTok)) {
5951 case CXToken_Identifier:
5952 case CXToken_Keyword:
5953 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005954 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005955 ->getNameStart());
5956
5957 case CXToken_Literal: {
5958 // We have stashed the starting pointer in the ptr_data field. Use it.
5959 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005960 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005961 }
5962
5963 case CXToken_Punctuation:
5964 case CXToken_Comment:
5965 break;
5966 }
5967
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005968 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005969 LOG_BAD_TU(TU);
5970 return cxstring::createEmpty();
5971 }
5972
Guy Benyei11169dd2012-12-18 14:30:41 +00005973 // We have to find the starting buffer pointer the hard way, by
5974 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005975 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005976 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005977 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005978
5979 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5980 std::pair<FileID, unsigned> LocInfo
5981 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5982 bool Invalid = false;
5983 StringRef Buffer
5984 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5985 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005986 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005987
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005988 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005989}
5990
5991CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005992 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005993 LOG_BAD_TU(TU);
5994 return clang_getNullLocation();
5995 }
5996
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005997 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005998 if (!CXXUnit)
5999 return clang_getNullLocation();
6000
6001 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
6002 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
6003}
6004
6005CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006006 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006007 LOG_BAD_TU(TU);
6008 return clang_getNullRange();
6009 }
6010
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006011 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006012 if (!CXXUnit)
6013 return clang_getNullRange();
6014
6015 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
6016 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
6017}
6018
6019static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
6020 SmallVectorImpl<CXToken> &CXTokens) {
6021 SourceManager &SourceMgr = CXXUnit->getSourceManager();
6022 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006023 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00006024 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006025 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00006026
6027 // Cannot tokenize across files.
6028 if (BeginLocInfo.first != EndLocInfo.first)
6029 return;
6030
6031 // Create a lexer
6032 bool Invalid = false;
6033 StringRef Buffer
6034 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
6035 if (Invalid)
6036 return;
6037
6038 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
6039 CXXUnit->getASTContext().getLangOpts(),
6040 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
6041 Lex.SetCommentRetentionState(true);
6042
6043 // Lex tokens until we hit the end of the range.
6044 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
6045 Token Tok;
6046 bool previousWasAt = false;
6047 do {
6048 // Lex the next token
6049 Lex.LexFromRawLexer(Tok);
6050 if (Tok.is(tok::eof))
6051 break;
6052
6053 // Initialize the CXToken.
6054 CXToken CXTok;
6055
6056 // - Common fields
6057 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
6058 CXTok.int_data[2] = Tok.getLength();
6059 CXTok.int_data[3] = 0;
6060
6061 // - Kind-specific fields
6062 if (Tok.isLiteral()) {
6063 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006064 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00006065 } else if (Tok.is(tok::raw_identifier)) {
6066 // Lookup the identifier to determine whether we have a keyword.
6067 IdentifierInfo *II
6068 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
6069
6070 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
6071 CXTok.int_data[0] = CXToken_Keyword;
6072 }
6073 else {
6074 CXTok.int_data[0] = Tok.is(tok::identifier)
6075 ? CXToken_Identifier
6076 : CXToken_Keyword;
6077 }
6078 CXTok.ptr_data = II;
6079 } else if (Tok.is(tok::comment)) {
6080 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00006081 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006082 } else {
6083 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00006084 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006085 }
6086 CXTokens.push_back(CXTok);
6087 previousWasAt = Tok.is(tok::at);
6088 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
6089}
6090
6091void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
6092 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006093 LOG_FUNC_SECTION {
6094 *Log << TU << ' ' << Range;
6095 }
6096
Guy Benyei11169dd2012-12-18 14:30:41 +00006097 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00006098 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006099 if (NumTokens)
6100 *NumTokens = 0;
6101
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006102 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006103 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00006104 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006105 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00006106
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006107 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006108 if (!CXXUnit || !Tokens || !NumTokens)
6109 return;
6110
6111 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
6112
6113 SourceRange R = cxloc::translateCXSourceRange(Range);
6114 if (R.isInvalid())
6115 return;
6116
6117 SmallVector<CXToken, 32> CXTokens;
6118 getTokens(CXXUnit, R, CXTokens);
6119
6120 if (CXTokens.empty())
6121 return;
6122
6123 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
6124 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
6125 *NumTokens = CXTokens.size();
6126}
6127
6128void clang_disposeTokens(CXTranslationUnit TU,
6129 CXToken *Tokens, unsigned NumTokens) {
6130 free(Tokens);
6131}
6132
6133} // end: extern "C"
6134
6135//===----------------------------------------------------------------------===//
6136// Token annotation APIs.
6137//===----------------------------------------------------------------------===//
6138
Guy Benyei11169dd2012-12-18 14:30:41 +00006139static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
6140 CXCursor parent,
6141 CXClientData client_data);
6142static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
6143 CXClientData client_data);
6144
6145namespace {
6146class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00006147 CXToken *Tokens;
6148 CXCursor *Cursors;
6149 unsigned NumTokens;
6150 unsigned TokIdx;
6151 unsigned PreprocessingTokIdx;
6152 CursorVisitor AnnotateVis;
6153 SourceManager &SrcMgr;
6154 bool HasContextSensitiveKeywords;
6155
6156 struct PostChildrenInfo {
6157 CXCursor Cursor;
6158 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006159 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006160 unsigned BeforeChildrenTokenIdx;
6161 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00006162 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006163
6164 CXToken &getTok(unsigned Idx) {
6165 assert(Idx < NumTokens);
6166 return Tokens[Idx];
6167 }
6168 const CXToken &getTok(unsigned Idx) const {
6169 assert(Idx < NumTokens);
6170 return Tokens[Idx];
6171 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006172 bool MoreTokens() const { return TokIdx < NumTokens; }
6173 unsigned NextToken() const { return TokIdx; }
6174 void AdvanceToken() { ++TokIdx; }
6175 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006176 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006177 }
6178 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006179 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006180 }
6181 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006182 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006183 }
6184
6185 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006186 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00006187 SourceRange);
6188
6189public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006190 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006191 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006192 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00006193 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006194 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00006195 AnnotateTokensVisitor, this,
6196 /*VisitPreprocessorLast=*/true,
6197 /*VisitIncludedEntities=*/false,
6198 RegionOfInterest,
6199 /*VisitDeclsOnly=*/false,
6200 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006201 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00006202 HasContextSensitiveKeywords(false) { }
6203
6204 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
6205 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
6206 bool postVisitChildren(CXCursor cursor);
6207 void AnnotateTokens();
6208
6209 /// \brief Determine whether the annotator saw any cursors that have
6210 /// context-sensitive keywords.
6211 bool hasContextSensitiveKeywords() const {
6212 return HasContextSensitiveKeywords;
6213 }
6214
6215 ~AnnotateTokensWorker() {
6216 assert(PostChildrenInfos.empty());
6217 }
6218};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00006219}
Guy Benyei11169dd2012-12-18 14:30:41 +00006220
6221void AnnotateTokensWorker::AnnotateTokens() {
6222 // Walk the AST within the region of interest, annotating tokens
6223 // along the way.
6224 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006225}
Guy Benyei11169dd2012-12-18 14:30:41 +00006226
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006227static inline void updateCursorAnnotation(CXCursor &Cursor,
6228 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006229 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00006230 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006231 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00006232}
6233
6234/// \brief It annotates and advances tokens with a cursor until the comparison
6235//// between the cursor location and the source range is the same as
6236/// \arg compResult.
6237///
6238/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
6239/// Pass RangeOverlap to annotate tokens inside a range.
6240void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
6241 RangeComparisonResult compResult,
6242 SourceRange range) {
6243 while (MoreTokens()) {
6244 const unsigned I = NextToken();
6245 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006246 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
6247 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00006248
6249 SourceLocation TokLoc = GetTokenLoc(I);
6250 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006251 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00006252 AdvanceToken();
6253 continue;
6254 }
6255 break;
6256 }
6257}
6258
6259/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006260/// \returns true if it advanced beyond all macro tokens, false otherwise.
6261bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00006262 CXCursor updateC,
6263 RangeComparisonResult compResult,
6264 SourceRange range) {
6265 assert(MoreTokens());
6266 assert(isFunctionMacroToken(NextToken()) &&
6267 "Should be called only for macro arg tokens");
6268
6269 // This works differently than annotateAndAdvanceTokens; because expanded
6270 // macro arguments can have arbitrary translation-unit source order, we do not
6271 // advance the token index one by one until a token fails the range test.
6272 // We only advance once past all of the macro arg tokens if all of them
6273 // pass the range test. If one of them fails we keep the token index pointing
6274 // at the start of the macro arg tokens so that the failing token will be
6275 // annotated by a subsequent annotation try.
6276
6277 bool atLeastOneCompFail = false;
6278
6279 unsigned I = NextToken();
6280 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
6281 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
6282 if (TokLoc.isFileID())
6283 continue; // not macro arg token, it's parens or comma.
6284 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
6285 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
6286 Cursors[I] = updateC;
6287 } else
6288 atLeastOneCompFail = true;
6289 }
6290
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006291 if (atLeastOneCompFail)
6292 return false;
6293
6294 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
6295 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00006296}
6297
6298enum CXChildVisitResult
6299AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006300 SourceRange cursorRange = getRawCursorExtent(cursor);
6301 if (cursorRange.isInvalid())
6302 return CXChildVisit_Recurse;
6303
6304 if (!HasContextSensitiveKeywords) {
6305 // Objective-C properties can have context-sensitive keywords.
6306 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006307 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006308 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
6309 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
6310 }
6311 // Objective-C methods can have context-sensitive keywords.
6312 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
6313 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006314 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00006315 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
6316 if (Method->getObjCDeclQualifier())
6317 HasContextSensitiveKeywords = true;
6318 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00006319 for (const auto *P : Method->params()) {
6320 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006321 HasContextSensitiveKeywords = true;
6322 break;
6323 }
6324 }
6325 }
6326 }
6327 }
6328 // C++ methods can have context-sensitive keywords.
6329 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006330 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00006331 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
6332 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
6333 HasContextSensitiveKeywords = true;
6334 }
6335 }
6336 // C++ classes can have context-sensitive keywords.
6337 else if (cursor.kind == CXCursor_StructDecl ||
6338 cursor.kind == CXCursor_ClassDecl ||
6339 cursor.kind == CXCursor_ClassTemplate ||
6340 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006341 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006342 if (D->hasAttr<FinalAttr>())
6343 HasContextSensitiveKeywords = true;
6344 }
6345 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00006346
6347 // Don't override a property annotation with its getter/setter method.
6348 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
6349 parent.kind == CXCursor_ObjCPropertyDecl)
6350 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00006351
6352 if (clang_isPreprocessing(cursor.kind)) {
6353 // Items in the preprocessing record are kept separate from items in
6354 // declarations, so we keep a separate token index.
6355 unsigned SavedTokIdx = TokIdx;
6356 TokIdx = PreprocessingTokIdx;
6357
6358 // Skip tokens up until we catch up to the beginning of the preprocessing
6359 // entry.
6360 while (MoreTokens()) {
6361 const unsigned I = NextToken();
6362 SourceLocation TokLoc = GetTokenLoc(I);
6363 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
6364 case RangeBefore:
6365 AdvanceToken();
6366 continue;
6367 case RangeAfter:
6368 case RangeOverlap:
6369 break;
6370 }
6371 break;
6372 }
6373
6374 // Look at all of the tokens within this range.
6375 while (MoreTokens()) {
6376 const unsigned I = NextToken();
6377 SourceLocation TokLoc = GetTokenLoc(I);
6378 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
6379 case RangeBefore:
6380 llvm_unreachable("Infeasible");
6381 case RangeAfter:
6382 break;
6383 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006384 // For macro expansions, just note where the beginning of the macro
6385 // expansion occurs.
6386 if (cursor.kind == CXCursor_MacroExpansion) {
6387 if (TokLoc == cursorRange.getBegin())
6388 Cursors[I] = cursor;
6389 AdvanceToken();
6390 break;
6391 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006392 // We may have already annotated macro names inside macro definitions.
6393 if (Cursors[I].kind != CXCursor_MacroExpansion)
6394 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00006395 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00006396 continue;
6397 }
6398 break;
6399 }
6400
6401 // Save the preprocessing token index; restore the non-preprocessing
6402 // token index.
6403 PreprocessingTokIdx = TokIdx;
6404 TokIdx = SavedTokIdx;
6405 return CXChildVisit_Recurse;
6406 }
6407
6408 if (cursorRange.isInvalid())
6409 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006410
6411 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00006412 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006413 const enum CXCursorKind K = clang_getCursorKind(parent);
6414 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006415 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
6416 // Attributes are annotated out-of-order, skip tokens until we reach it.
6417 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00006418 ? clang_getNullCursor() : parent;
6419
6420 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
6421
6422 // Avoid having the cursor of an expression "overwrite" the annotation of the
6423 // variable declaration that it belongs to.
6424 // This can happen for C++ constructor expressions whose range generally
6425 // include the variable declaration, e.g.:
6426 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006427 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00006428 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00006429 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006430 const unsigned I = NextToken();
6431 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
6432 E->getLocStart() == D->getLocation() &&
6433 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006434 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00006435 AdvanceToken();
6436 }
6437 }
6438 }
6439
6440 // Before recursing into the children keep some state that we are going
6441 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
6442 // extra work after the child nodes are visited.
6443 // Note that we don't call VisitChildren here to avoid traversing statements
6444 // code-recursively which can blow the stack.
6445
6446 PostChildrenInfo Info;
6447 Info.Cursor = cursor;
6448 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006449 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006450 Info.BeforeChildrenTokenIdx = NextToken();
6451 PostChildrenInfos.push_back(Info);
6452
6453 return CXChildVisit_Recurse;
6454}
6455
6456bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
6457 if (PostChildrenInfos.empty())
6458 return false;
6459 const PostChildrenInfo &Info = PostChildrenInfos.back();
6460 if (!clang_equalCursors(Info.Cursor, cursor))
6461 return false;
6462
6463 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
6464 const unsigned AfterChildren = NextToken();
6465 SourceRange cursorRange = Info.CursorRange;
6466
6467 // Scan the tokens that are at the end of the cursor, but are not captured
6468 // but the child cursors.
6469 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
6470
6471 // Scan the tokens that are at the beginning of the cursor, but are not
6472 // capture by the child cursors.
6473 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
6474 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
6475 break;
6476
6477 Cursors[I] = cursor;
6478 }
6479
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006480 // Attributes are annotated out-of-order, rewind TokIdx to when we first
6481 // encountered the attribute cursor.
6482 if (clang_isAttribute(cursor.kind))
6483 TokIdx = Info.BeforeReachingCursorIdx;
6484
Guy Benyei11169dd2012-12-18 14:30:41 +00006485 PostChildrenInfos.pop_back();
6486 return false;
6487}
6488
6489static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
6490 CXCursor parent,
6491 CXClientData client_data) {
6492 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
6493}
6494
6495static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
6496 CXClientData client_data) {
6497 return static_cast<AnnotateTokensWorker*>(client_data)->
6498 postVisitChildren(cursor);
6499}
6500
6501namespace {
6502
6503/// \brief Uses the macro expansions in the preprocessing record to find
6504/// and mark tokens that are macro arguments. This info is used by the
6505/// AnnotateTokensWorker.
6506class MarkMacroArgTokensVisitor {
6507 SourceManager &SM;
6508 CXToken *Tokens;
6509 unsigned NumTokens;
6510 unsigned CurIdx;
6511
6512public:
6513 MarkMacroArgTokensVisitor(SourceManager &SM,
6514 CXToken *tokens, unsigned numTokens)
6515 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
6516
6517 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
6518 if (cursor.kind != CXCursor_MacroExpansion)
6519 return CXChildVisit_Continue;
6520
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006521 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00006522 if (macroRange.getBegin() == macroRange.getEnd())
6523 return CXChildVisit_Continue; // it's not a function macro.
6524
6525 for (; CurIdx < NumTokens; ++CurIdx) {
6526 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
6527 macroRange.getBegin()))
6528 break;
6529 }
6530
6531 if (CurIdx == NumTokens)
6532 return CXChildVisit_Break;
6533
6534 for (; CurIdx < NumTokens; ++CurIdx) {
6535 SourceLocation tokLoc = getTokenLoc(CurIdx);
6536 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
6537 break;
6538
6539 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
6540 }
6541
6542 if (CurIdx == NumTokens)
6543 return CXChildVisit_Break;
6544
6545 return CXChildVisit_Continue;
6546 }
6547
6548private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006549 CXToken &getTok(unsigned Idx) {
6550 assert(Idx < NumTokens);
6551 return Tokens[Idx];
6552 }
6553 const CXToken &getTok(unsigned Idx) const {
6554 assert(Idx < NumTokens);
6555 return Tokens[Idx];
6556 }
6557
Guy Benyei11169dd2012-12-18 14:30:41 +00006558 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006559 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006560 }
6561
6562 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
6563 // The third field is reserved and currently not used. Use it here
6564 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006565 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00006566 }
6567};
6568
6569} // end anonymous namespace
6570
6571static CXChildVisitResult
6572MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
6573 CXClientData client_data) {
6574 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
6575 parent);
6576}
6577
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006578/// \brief Used by \c annotatePreprocessorTokens.
6579/// \returns true if lexing was finished, false otherwise.
6580static bool lexNext(Lexer &Lex, Token &Tok,
6581 unsigned &NextIdx, unsigned NumTokens) {
6582 if (NextIdx >= NumTokens)
6583 return true;
6584
6585 ++NextIdx;
6586 Lex.LexFromRawLexer(Tok);
Alexander Kornienko1a9f1842015-12-28 15:24:08 +00006587 return Tok.is(tok::eof);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006588}
6589
Guy Benyei11169dd2012-12-18 14:30:41 +00006590static void annotatePreprocessorTokens(CXTranslationUnit TU,
6591 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006592 CXCursor *Cursors,
6593 CXToken *Tokens,
6594 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006595 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006596
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006597 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00006598 SourceManager &SourceMgr = CXXUnit->getSourceManager();
6599 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006600 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00006601 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006602 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00006603
6604 if (BeginLocInfo.first != EndLocInfo.first)
6605 return;
6606
6607 StringRef Buffer;
6608 bool Invalid = false;
6609 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
6610 if (Buffer.empty() || Invalid)
6611 return;
6612
6613 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
6614 CXXUnit->getASTContext().getLangOpts(),
6615 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
6616 Buffer.end());
6617 Lex.SetCommentRetentionState(true);
6618
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006619 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006620 // Lex tokens in raw mode until we hit the end of the range, to avoid
6621 // entering #includes or expanding macros.
6622 while (true) {
6623 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006624 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6625 break;
6626 unsigned TokIdx = NextIdx-1;
6627 assert(Tok.getLocation() ==
6628 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006629
6630 reprocess:
6631 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006632 // We have found a preprocessing directive. Annotate the tokens
6633 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00006634 //
6635 // FIXME: Some simple tests here could identify macro definitions and
6636 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006637
6638 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006639 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6640 break;
6641
Craig Topper69186e72014-06-08 08:38:04 +00006642 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00006643 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006644 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6645 break;
6646
6647 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00006648 IdentifierInfo &II =
6649 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006650 SourceLocation MappedTokLoc =
6651 CXXUnit->mapLocationToPreamble(Tok.getLocation());
6652 MI = getMacroInfo(II, MappedTokLoc, TU);
6653 }
6654 }
6655
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006656 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00006657 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006658 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
6659 finished = true;
6660 break;
6661 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006662 // If we are in a macro definition, check if the token was ever a
6663 // macro name and annotate it if that's the case.
6664 if (MI) {
6665 SourceLocation SaveLoc = Tok.getLocation();
6666 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
Richard Smith66a81862015-05-04 02:25:31 +00006667 MacroDefinitionRecord *MacroDef =
6668 checkForMacroInMacroDefinition(MI, Tok, TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006669 Tok.setLocation(SaveLoc);
6670 if (MacroDef)
Richard Smith66a81862015-05-04 02:25:31 +00006671 Cursors[NextIdx - 1] =
6672 MakeMacroExpansionCursor(MacroDef, Tok.getLocation(), TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006673 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006674 } while (!Tok.isAtStartOfLine());
6675
6676 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
6677 assert(TokIdx <= LastIdx);
6678 SourceLocation EndLoc =
6679 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
6680 CXCursor Cursor =
6681 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
6682
6683 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006684 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006685
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006686 if (finished)
6687 break;
6688 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00006689 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006690 }
6691}
6692
6693// This gets run a separate thread to avoid stack blowout.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006694static void clang_annotateTokensImpl(CXTranslationUnit TU, ASTUnit *CXXUnit,
6695 CXToken *Tokens, unsigned NumTokens,
6696 CXCursor *Cursors) {
Dmitri Gribenko183436e2013-01-26 21:49:50 +00006697 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006698 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
6699 setThreadBackgroundPriority();
6700
6701 // Determine the region of interest, which contains all of the tokens.
6702 SourceRange RegionOfInterest;
6703 RegionOfInterest.setBegin(
6704 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
6705 RegionOfInterest.setEnd(
6706 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
6707 Tokens[NumTokens-1])));
6708
Guy Benyei11169dd2012-12-18 14:30:41 +00006709 // Relex the tokens within the source range to look for preprocessing
6710 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006711 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006712
6713 // If begin location points inside a macro argument, set it to the expansion
6714 // location so we can have the full context when annotating semantically.
6715 {
6716 SourceManager &SM = CXXUnit->getSourceManager();
6717 SourceLocation Loc =
6718 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
6719 if (Loc.isMacroID())
6720 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
6721 }
6722
Guy Benyei11169dd2012-12-18 14:30:41 +00006723 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
6724 // Search and mark tokens that are macro argument expansions.
6725 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
6726 Tokens, NumTokens);
6727 CursorVisitor MacroArgMarker(TU,
6728 MarkMacroArgTokensVisitorDelegate, &Visitor,
6729 /*VisitPreprocessorLast=*/true,
6730 /*VisitIncludedEntities=*/false,
6731 RegionOfInterest);
6732 MacroArgMarker.visitPreprocessedEntitiesInRegion();
6733 }
6734
6735 // Annotate all of the source locations in the region of interest that map to
6736 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006737 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00006738
6739 // FIXME: We use a ridiculous stack size here because the data-recursion
6740 // algorithm uses a large stack frame than the non-data recursive version,
6741 // and AnnotationTokensWorker currently transforms the data-recursion
6742 // algorithm back into a traditional recursion by explicitly calling
6743 // VisitChildren(). We will need to remove this explicit recursive call.
6744 W.AnnotateTokens();
6745
6746 // If we ran into any entities that involve context-sensitive keywords,
6747 // take another pass through the tokens to mark them as such.
6748 if (W.hasContextSensitiveKeywords()) {
6749 for (unsigned I = 0; I != NumTokens; ++I) {
6750 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
6751 continue;
6752
6753 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
6754 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006755 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006756 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
6757 if (Property->getPropertyAttributesAsWritten() != 0 &&
6758 llvm::StringSwitch<bool>(II->getName())
6759 .Case("readonly", true)
6760 .Case("assign", true)
6761 .Case("unsafe_unretained", true)
6762 .Case("readwrite", true)
6763 .Case("retain", true)
6764 .Case("copy", true)
6765 .Case("nonatomic", true)
6766 .Case("atomic", true)
6767 .Case("getter", true)
6768 .Case("setter", true)
6769 .Case("strong", true)
6770 .Case("weak", true)
6771 .Default(false))
6772 Tokens[I].int_data[0] = CXToken_Keyword;
6773 }
6774 continue;
6775 }
6776
6777 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6778 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6779 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6780 if (llvm::StringSwitch<bool>(II->getName())
6781 .Case("in", true)
6782 .Case("out", true)
6783 .Case("inout", true)
6784 .Case("oneway", true)
6785 .Case("bycopy", true)
6786 .Case("byref", true)
6787 .Default(false))
6788 Tokens[I].int_data[0] = CXToken_Keyword;
6789 continue;
6790 }
6791
6792 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6793 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6794 Tokens[I].int_data[0] = CXToken_Keyword;
6795 continue;
6796 }
6797 }
6798 }
6799}
6800
6801extern "C" {
6802
6803void clang_annotateTokens(CXTranslationUnit TU,
6804 CXToken *Tokens, unsigned NumTokens,
6805 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006806 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006807 LOG_BAD_TU(TU);
6808 return;
6809 }
6810 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006811 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006812 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006813 }
6814
6815 LOG_FUNC_SECTION {
6816 *Log << TU << ' ';
6817 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6818 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6819 *Log << clang_getRange(bloc, eloc);
6820 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006821
6822 // Any token we don't specifically annotate will have a NULL cursor.
6823 CXCursor C = clang_getNullCursor();
6824 for (unsigned I = 0; I != NumTokens; ++I)
6825 Cursors[I] = C;
6826
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006827 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006828 if (!CXXUnit)
6829 return;
6830
6831 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006832
6833 auto AnnotateTokensImpl = [=]() {
6834 clang_annotateTokensImpl(TU, CXXUnit, Tokens, NumTokens, Cursors);
6835 };
Guy Benyei11169dd2012-12-18 14:30:41 +00006836 llvm::CrashRecoveryContext CRC;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006837 if (!RunSafely(CRC, AnnotateTokensImpl, GetSafetyThreadStackSize() * 2)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006838 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6839 }
6840}
6841
6842} // end: extern "C"
6843
6844//===----------------------------------------------------------------------===//
6845// Operations for querying linkage of a cursor.
6846//===----------------------------------------------------------------------===//
6847
6848extern "C" {
6849CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6850 if (!clang_isDeclaration(cursor.kind))
6851 return CXLinkage_Invalid;
6852
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006853 const Decl *D = cxcursor::getCursorDecl(cursor);
6854 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006855 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006856 case NoLinkage:
6857 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006858 case InternalLinkage: return CXLinkage_Internal;
6859 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6860 case ExternalLinkage: return CXLinkage_External;
6861 };
6862
6863 return CXLinkage_Invalid;
6864}
6865} // end: extern "C"
6866
6867//===----------------------------------------------------------------------===//
Ehsan Akhgari93697fa2015-11-23 19:56:46 +00006868// Operations for querying visibility of a cursor.
6869//===----------------------------------------------------------------------===//
6870
6871extern "C" {
6872CXVisibilityKind clang_getCursorVisibility(CXCursor cursor) {
6873 if (!clang_isDeclaration(cursor.kind))
6874 return CXVisibility_Invalid;
6875
6876 const Decl *D = cxcursor::getCursorDecl(cursor);
6877 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
6878 switch (ND->getVisibility()) {
6879 case HiddenVisibility: return CXVisibility_Hidden;
6880 case ProtectedVisibility: return CXVisibility_Protected;
6881 case DefaultVisibility: return CXVisibility_Default;
6882 };
6883
6884 return CXVisibility_Invalid;
6885}
6886} // end: extern "C"
6887
6888//===----------------------------------------------------------------------===//
Guy Benyei11169dd2012-12-18 14:30:41 +00006889// Operations for querying language of a cursor.
6890//===----------------------------------------------------------------------===//
6891
6892static CXLanguageKind getDeclLanguage(const Decl *D) {
6893 if (!D)
6894 return CXLanguage_C;
6895
6896 switch (D->getKind()) {
6897 default:
6898 break;
6899 case Decl::ImplicitParam:
6900 case Decl::ObjCAtDefsField:
6901 case Decl::ObjCCategory:
6902 case Decl::ObjCCategoryImpl:
6903 case Decl::ObjCCompatibleAlias:
6904 case Decl::ObjCImplementation:
6905 case Decl::ObjCInterface:
6906 case Decl::ObjCIvar:
6907 case Decl::ObjCMethod:
6908 case Decl::ObjCProperty:
6909 case Decl::ObjCPropertyImpl:
6910 case Decl::ObjCProtocol:
Douglas Gregor85f3f952015-07-07 03:57:15 +00006911 case Decl::ObjCTypeParam:
Guy Benyei11169dd2012-12-18 14:30:41 +00006912 return CXLanguage_ObjC;
6913 case Decl::CXXConstructor:
6914 case Decl::CXXConversion:
6915 case Decl::CXXDestructor:
6916 case Decl::CXXMethod:
6917 case Decl::CXXRecord:
6918 case Decl::ClassTemplate:
6919 case Decl::ClassTemplatePartialSpecialization:
6920 case Decl::ClassTemplateSpecialization:
6921 case Decl::Friend:
6922 case Decl::FriendTemplate:
6923 case Decl::FunctionTemplate:
6924 case Decl::LinkageSpec:
6925 case Decl::Namespace:
6926 case Decl::NamespaceAlias:
6927 case Decl::NonTypeTemplateParm:
6928 case Decl::StaticAssert:
6929 case Decl::TemplateTemplateParm:
6930 case Decl::TemplateTypeParm:
6931 case Decl::UnresolvedUsingTypename:
6932 case Decl::UnresolvedUsingValue:
6933 case Decl::Using:
6934 case Decl::UsingDirective:
6935 case Decl::UsingShadow:
6936 return CXLanguage_CPlusPlus;
6937 }
6938
6939 return CXLanguage_C;
6940}
6941
6942extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006943
6944static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6945 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
Manuel Klimek8e3a7ed2015-09-25 17:53:16 +00006946 return CXAvailability_NotAvailable;
Guy Benyei11169dd2012-12-18 14:30:41 +00006947
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006948 switch (D->getAvailability()) {
6949 case AR_Available:
6950 case AR_NotYetIntroduced:
6951 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006952 return getCursorAvailabilityForDecl(
6953 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006954 return CXAvailability_Available;
6955
6956 case AR_Deprecated:
6957 return CXAvailability_Deprecated;
6958
6959 case AR_Unavailable:
6960 return CXAvailability_NotAvailable;
6961 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006962
6963 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006964}
6965
Guy Benyei11169dd2012-12-18 14:30:41 +00006966enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6967 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006968 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6969 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006970
6971 return CXAvailability_Available;
6972}
6973
6974static CXVersion convertVersion(VersionTuple In) {
6975 CXVersion Out = { -1, -1, -1 };
6976 if (In.empty())
6977 return Out;
6978
6979 Out.Major = In.getMajor();
6980
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006981 Optional<unsigned> Minor = In.getMinor();
6982 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006983 Out.Minor = *Minor;
6984 else
6985 return Out;
6986
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006987 Optional<unsigned> Subminor = In.getSubminor();
6988 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006989 Out.Subminor = *Subminor;
6990
6991 return Out;
6992}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006993
6994static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6995 int *always_deprecated,
6996 CXString *deprecated_message,
6997 int *always_unavailable,
6998 CXString *unavailable_message,
6999 CXPlatformAvailability *availability,
7000 int availability_size) {
7001 bool HadAvailAttr = false;
7002 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00007003 for (auto A : D->attrs()) {
7004 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007005 HadAvailAttr = true;
7006 if (always_deprecated)
7007 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00007008 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00007009 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007010 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00007011 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007012 continue;
7013 }
7014
Aaron Ballmanb97112e2014-03-08 22:19:01 +00007015 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007016 HadAvailAttr = true;
7017 if (always_unavailable)
7018 *always_unavailable = 1;
7019 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00007020 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007021 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
7022 }
7023 continue;
7024 }
7025
Aaron Ballmanb97112e2014-03-08 22:19:01 +00007026 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007027 HadAvailAttr = true;
7028 if (N < availability_size) {
7029 availability[N].Platform
7030 = cxstring::createDup(Avail->getPlatform()->getName());
7031 availability[N].Introduced = convertVersion(Avail->getIntroduced());
7032 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
7033 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
7034 availability[N].Unavailable = Avail->getUnavailable();
7035 availability[N].Message = cxstring::createDup(Avail->getMessage());
7036 }
7037 ++N;
7038 }
7039 }
7040
7041 if (!HadAvailAttr)
7042 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
7043 return getCursorPlatformAvailabilityForDecl(
7044 cast<Decl>(EnumConst->getDeclContext()),
7045 always_deprecated,
7046 deprecated_message,
7047 always_unavailable,
7048 unavailable_message,
7049 availability,
7050 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00007051
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007052 return N;
7053}
7054
Guy Benyei11169dd2012-12-18 14:30:41 +00007055int clang_getCursorPlatformAvailability(CXCursor cursor,
7056 int *always_deprecated,
7057 CXString *deprecated_message,
7058 int *always_unavailable,
7059 CXString *unavailable_message,
7060 CXPlatformAvailability *availability,
7061 int availability_size) {
7062 if (always_deprecated)
7063 *always_deprecated = 0;
7064 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007065 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00007066 if (always_unavailable)
7067 *always_unavailable = 0;
7068 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007069 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007070
Guy Benyei11169dd2012-12-18 14:30:41 +00007071 if (!clang_isDeclaration(cursor.kind))
7072 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007073
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007074 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00007075 if (!D)
7076 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007077
7078 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
7079 deprecated_message,
7080 always_unavailable,
7081 unavailable_message,
7082 availability,
7083 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00007084}
7085
7086void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
7087 clang_disposeString(availability->Platform);
7088 clang_disposeString(availability->Message);
7089}
7090
7091CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
7092 if (clang_isDeclaration(cursor.kind))
7093 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
7094
7095 return CXLanguage_Invalid;
7096}
7097
7098 /// \brief If the given cursor is the "templated" declaration
7099 /// descibing a class or function template, return the class or
7100 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007101static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007102 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00007103 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007104
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007105 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00007106 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
7107 return FunTmpl;
7108
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007109 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00007110 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
7111 return ClassTmpl;
7112
7113 return D;
7114}
7115
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00007116
7117enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
7118 StorageClass sc = SC_None;
7119 const Decl *D = getCursorDecl(C);
7120 if (D) {
7121 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
7122 sc = FD->getStorageClass();
7123 } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
7124 sc = VD->getStorageClass();
7125 } else {
7126 return CX_SC_Invalid;
7127 }
7128 } else {
7129 return CX_SC_Invalid;
7130 }
7131 switch (sc) {
7132 case SC_None:
7133 return CX_SC_None;
7134 case SC_Extern:
7135 return CX_SC_Extern;
7136 case SC_Static:
7137 return CX_SC_Static;
7138 case SC_PrivateExtern:
7139 return CX_SC_PrivateExtern;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00007140 case SC_Auto:
7141 return CX_SC_Auto;
7142 case SC_Register:
7143 return CX_SC_Register;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00007144 }
Kaelyn Takataab61e702014-10-15 18:03:26 +00007145 llvm_unreachable("Unhandled storage class!");
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00007146}
7147
Guy Benyei11169dd2012-12-18 14:30:41 +00007148CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
7149 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007150 if (const Decl *D = getCursorDecl(cursor)) {
7151 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00007152 if (!DC)
7153 return clang_getNullCursor();
7154
7155 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
7156 getCursorTU(cursor));
7157 }
7158 }
7159
7160 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007161 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00007162 return MakeCXCursor(D, getCursorTU(cursor));
7163 }
7164
7165 return clang_getNullCursor();
7166}
7167
7168CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
7169 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007170 if (const Decl *D = getCursorDecl(cursor)) {
7171 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00007172 if (!DC)
7173 return clang_getNullCursor();
7174
7175 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
7176 getCursorTU(cursor));
7177 }
7178 }
7179
7180 // FIXME: Note that we can't easily compute the lexical context of a
7181 // statement or expression, so we return nothing.
7182 return clang_getNullCursor();
7183}
7184
7185CXFile clang_getIncludedFile(CXCursor cursor) {
7186 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00007187 return nullptr;
7188
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007189 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00007190 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00007191}
7192
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00007193unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
7194 if (C.kind != CXCursor_ObjCPropertyDecl)
7195 return CXObjCPropertyAttr_noattr;
7196
7197 unsigned Result = CXObjCPropertyAttr_noattr;
7198 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
7199 ObjCPropertyDecl::PropertyAttributeKind Attr =
7200 PD->getPropertyAttributesAsWritten();
7201
7202#define SET_CXOBJCPROP_ATTR(A) \
7203 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
7204 Result |= CXObjCPropertyAttr_##A
7205 SET_CXOBJCPROP_ATTR(readonly);
7206 SET_CXOBJCPROP_ATTR(getter);
7207 SET_CXOBJCPROP_ATTR(assign);
7208 SET_CXOBJCPROP_ATTR(readwrite);
7209 SET_CXOBJCPROP_ATTR(retain);
7210 SET_CXOBJCPROP_ATTR(copy);
7211 SET_CXOBJCPROP_ATTR(nonatomic);
7212 SET_CXOBJCPROP_ATTR(setter);
7213 SET_CXOBJCPROP_ATTR(atomic);
7214 SET_CXOBJCPROP_ATTR(weak);
7215 SET_CXOBJCPROP_ATTR(strong);
7216 SET_CXOBJCPROP_ATTR(unsafe_unretained);
7217#undef SET_CXOBJCPROP_ATTR
7218
7219 return Result;
7220}
7221
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00007222unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
7223 if (!clang_isDeclaration(C.kind))
7224 return CXObjCDeclQualifier_None;
7225
7226 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
7227 const Decl *D = getCursorDecl(C);
7228 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
7229 QT = MD->getObjCDeclQualifier();
7230 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
7231 QT = PD->getObjCDeclQualifier();
7232 if (QT == Decl::OBJC_TQ_None)
7233 return CXObjCDeclQualifier_None;
7234
7235 unsigned Result = CXObjCDeclQualifier_None;
7236 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
7237 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
7238 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
7239 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
7240 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
7241 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
7242
7243 return Result;
7244}
7245
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00007246unsigned clang_Cursor_isObjCOptional(CXCursor C) {
7247 if (!clang_isDeclaration(C.kind))
7248 return 0;
7249
7250 const Decl *D = getCursorDecl(C);
7251 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
7252 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
7253 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
7254 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
7255
7256 return 0;
7257}
7258
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00007259unsigned clang_Cursor_isVariadic(CXCursor C) {
7260 if (!clang_isDeclaration(C.kind))
7261 return 0;
7262
7263 const Decl *D = getCursorDecl(C);
7264 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
7265 return FD->isVariadic();
7266 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
7267 return MD->isVariadic();
7268
7269 return 0;
7270}
7271
Guy Benyei11169dd2012-12-18 14:30:41 +00007272CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
7273 if (!clang_isDeclaration(C.kind))
7274 return clang_getNullRange();
7275
7276 const Decl *D = getCursorDecl(C);
7277 ASTContext &Context = getCursorContext(C);
7278 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
7279 if (!RC)
7280 return clang_getNullRange();
7281
7282 return cxloc::translateSourceRange(Context, RC->getSourceRange());
7283}
7284
7285CXString clang_Cursor_getRawCommentText(CXCursor C) {
7286 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00007287 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00007288
7289 const Decl *D = getCursorDecl(C);
7290 ASTContext &Context = getCursorContext(C);
7291 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
7292 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
7293 StringRef();
7294
7295 // Don't duplicate the string because RawText points directly into source
7296 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007297 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00007298}
7299
7300CXString clang_Cursor_getBriefCommentText(CXCursor C) {
7301 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00007302 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00007303
7304 const Decl *D = getCursorDecl(C);
7305 const ASTContext &Context = getCursorContext(C);
7306 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
7307
7308 if (RC) {
7309 StringRef BriefText = RC->getBriefText(Context);
7310
7311 // Don't duplicate the string because RawComment ensures that this memory
7312 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007313 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00007314 }
7315
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00007316 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00007317}
7318
Guy Benyei11169dd2012-12-18 14:30:41 +00007319CXModule clang_Cursor_getModule(CXCursor C) {
7320 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007321 if (const ImportDecl *ImportD =
7322 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00007323 return ImportD->getImportedModule();
7324 }
7325
Craig Topper69186e72014-06-08 08:38:04 +00007326 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007327}
7328
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00007329CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
7330 if (isNotUsableTU(TU)) {
7331 LOG_BAD_TU(TU);
7332 return nullptr;
7333 }
7334 if (!File)
7335 return nullptr;
7336 FileEntry *FE = static_cast<FileEntry *>(File);
7337
7338 ASTUnit &Unit = *cxtu::getASTUnit(TU);
7339 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
7340 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
7341
Richard Smithfeb54b62014-10-23 02:01:19 +00007342 return Header.getModule();
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00007343}
7344
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00007345CXFile clang_Module_getASTFile(CXModule CXMod) {
7346 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00007347 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00007348 Module *Mod = static_cast<Module*>(CXMod);
7349 return const_cast<FileEntry *>(Mod->getASTFile());
7350}
7351
Guy Benyei11169dd2012-12-18 14:30:41 +00007352CXModule clang_Module_getParent(CXModule CXMod) {
7353 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00007354 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007355 Module *Mod = static_cast<Module*>(CXMod);
7356 return Mod->Parent;
7357}
7358
7359CXString clang_Module_getName(CXModule CXMod) {
7360 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007361 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00007362 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007363 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00007364}
7365
7366CXString clang_Module_getFullName(CXModule CXMod) {
7367 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007368 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00007369 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007370 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00007371}
7372
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00007373int clang_Module_isSystem(CXModule CXMod) {
7374 if (!CXMod)
7375 return 0;
7376 Module *Mod = static_cast<Module*>(CXMod);
7377 return Mod->IsSystem;
7378}
7379
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007380unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
7381 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007382 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007383 LOG_BAD_TU(TU);
7384 return 0;
7385 }
7386 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00007387 return 0;
7388 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007389 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
7390 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
7391 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00007392}
7393
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007394CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
7395 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007396 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007397 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00007398 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007399 }
7400 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00007401 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007402 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007403 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00007404
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007405 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
7406 if (Index < TopHeaders.size())
7407 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00007408
Craig Topper69186e72014-06-08 08:38:04 +00007409 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007410}
7411
7412} // end: extern "C"
7413
7414//===----------------------------------------------------------------------===//
7415// C++ AST instrospection.
7416//===----------------------------------------------------------------------===//
7417
7418extern "C" {
Saleem Abdulrasool6ea75db2015-10-27 15:50:22 +00007419unsigned clang_CXXField_isMutable(CXCursor C) {
7420 if (!clang_isDeclaration(C.kind))
7421 return 0;
7422
7423 if (const auto D = cxcursor::getCursorDecl(C))
7424 if (const auto FD = dyn_cast_or_null<FieldDecl>(D))
7425 return FD->isMutable() ? 1 : 0;
7426 return 0;
7427}
7428
Dmitri Gribenko62770be2013-05-17 18:38:35 +00007429unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
7430 if (!clang_isDeclaration(C.kind))
7431 return 0;
7432
Dmitri Gribenko62770be2013-05-17 18:38:35 +00007433 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007434 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007435 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00007436 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
7437}
7438
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00007439unsigned clang_CXXMethod_isConst(CXCursor C) {
7440 if (!clang_isDeclaration(C.kind))
7441 return 0;
7442
7443 const Decl *D = cxcursor::getCursorDecl(C);
7444 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007445 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00007446 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
7447}
7448
Guy Benyei11169dd2012-12-18 14:30:41 +00007449unsigned clang_CXXMethod_isStatic(CXCursor C) {
7450 if (!clang_isDeclaration(C.kind))
7451 return 0;
7452
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007453 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007454 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007455 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007456 return (Method && Method->isStatic()) ? 1 : 0;
7457}
7458
7459unsigned clang_CXXMethod_isVirtual(CXCursor C) {
7460 if (!clang_isDeclaration(C.kind))
7461 return 0;
7462
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007463 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007464 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007465 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007466 return (Method && Method->isVirtual()) ? 1 : 0;
7467}
7468} // end: extern "C"
7469
7470//===----------------------------------------------------------------------===//
7471// Attribute introspection.
7472//===----------------------------------------------------------------------===//
7473
7474extern "C" {
7475CXType clang_getIBOutletCollectionType(CXCursor C) {
7476 if (C.kind != CXCursor_IBOutletCollectionAttr)
7477 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
7478
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00007479 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00007480 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
7481
7482 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
7483}
7484} // end: extern "C"
7485
7486//===----------------------------------------------------------------------===//
7487// Inspecting memory usage.
7488//===----------------------------------------------------------------------===//
7489
7490typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
7491
7492static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
7493 enum CXTUResourceUsageKind k,
7494 unsigned long amount) {
7495 CXTUResourceUsageEntry entry = { k, amount };
7496 entries.push_back(entry);
7497}
7498
7499extern "C" {
7500
7501const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
7502 const char *str = "";
7503 switch (kind) {
7504 case CXTUResourceUsage_AST:
7505 str = "ASTContext: expressions, declarations, and types";
7506 break;
7507 case CXTUResourceUsage_Identifiers:
7508 str = "ASTContext: identifiers";
7509 break;
7510 case CXTUResourceUsage_Selectors:
7511 str = "ASTContext: selectors";
7512 break;
7513 case CXTUResourceUsage_GlobalCompletionResults:
7514 str = "Code completion: cached global results";
7515 break;
7516 case CXTUResourceUsage_SourceManagerContentCache:
7517 str = "SourceManager: content cache allocator";
7518 break;
7519 case CXTUResourceUsage_AST_SideTables:
7520 str = "ASTContext: side tables";
7521 break;
7522 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
7523 str = "SourceManager: malloc'ed memory buffers";
7524 break;
7525 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
7526 str = "SourceManager: mmap'ed memory buffers";
7527 break;
7528 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
7529 str = "ExternalASTSource: malloc'ed memory buffers";
7530 break;
7531 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
7532 str = "ExternalASTSource: mmap'ed memory buffers";
7533 break;
7534 case CXTUResourceUsage_Preprocessor:
7535 str = "Preprocessor: malloc'ed memory";
7536 break;
7537 case CXTUResourceUsage_PreprocessingRecord:
7538 str = "Preprocessor: PreprocessingRecord";
7539 break;
7540 case CXTUResourceUsage_SourceManager_DataStructures:
7541 str = "SourceManager: data structures and tables";
7542 break;
7543 case CXTUResourceUsage_Preprocessor_HeaderSearch:
7544 str = "Preprocessor: header search tables";
7545 break;
7546 }
7547 return str;
7548}
7549
7550CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007551 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007552 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00007553 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00007554 return usage;
7555 }
7556
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007557 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00007558 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00007559 ASTContext &astContext = astUnit->getASTContext();
7560
7561 // How much memory is used by AST nodes and types?
7562 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
7563 (unsigned long) astContext.getASTAllocatedMemory());
7564
7565 // How much memory is used by identifiers?
7566 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
7567 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
7568
7569 // How much memory is used for selectors?
7570 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
7571 (unsigned long) astContext.Selectors.getTotalMemory());
7572
7573 // How much memory is used by ASTContext's side tables?
7574 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
7575 (unsigned long) astContext.getSideTableAllocatedMemory());
7576
7577 // How much memory is used for caching global code completion results?
7578 unsigned long completionBytes = 0;
7579 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00007580 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007581 completionBytes = completionAllocator->getTotalMemory();
7582 }
7583 createCXTUResourceUsageEntry(*entries,
7584 CXTUResourceUsage_GlobalCompletionResults,
7585 completionBytes);
7586
7587 // How much memory is being used by SourceManager's content cache?
7588 createCXTUResourceUsageEntry(*entries,
7589 CXTUResourceUsage_SourceManagerContentCache,
7590 (unsigned long) astContext.getSourceManager().getContentCacheSize());
7591
7592 // How much memory is being used by the MemoryBuffer's in SourceManager?
7593 const SourceManager::MemoryBufferSizes &srcBufs =
7594 astUnit->getSourceManager().getMemoryBufferSizes();
7595
7596 createCXTUResourceUsageEntry(*entries,
7597 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
7598 (unsigned long) srcBufs.malloc_bytes);
7599 createCXTUResourceUsageEntry(*entries,
7600 CXTUResourceUsage_SourceManager_Membuffer_MMap,
7601 (unsigned long) srcBufs.mmap_bytes);
7602 createCXTUResourceUsageEntry(*entries,
7603 CXTUResourceUsage_SourceManager_DataStructures,
7604 (unsigned long) astContext.getSourceManager()
7605 .getDataStructureSizes());
7606
7607 // How much memory is being used by the ExternalASTSource?
7608 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
7609 const ExternalASTSource::MemoryBufferSizes &sizes =
7610 esrc->getMemoryBufferSizes();
7611
7612 createCXTUResourceUsageEntry(*entries,
7613 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
7614 (unsigned long) sizes.malloc_bytes);
7615 createCXTUResourceUsageEntry(*entries,
7616 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
7617 (unsigned long) sizes.mmap_bytes);
7618 }
7619
7620 // How much memory is being used by the Preprocessor?
7621 Preprocessor &pp = astUnit->getPreprocessor();
7622 createCXTUResourceUsageEntry(*entries,
7623 CXTUResourceUsage_Preprocessor,
7624 pp.getTotalMemory());
7625
7626 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
7627 createCXTUResourceUsageEntry(*entries,
7628 CXTUResourceUsage_PreprocessingRecord,
7629 pRec->getTotalMemory());
7630 }
7631
7632 createCXTUResourceUsageEntry(*entries,
7633 CXTUResourceUsage_Preprocessor_HeaderSearch,
7634 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00007635
Guy Benyei11169dd2012-12-18 14:30:41 +00007636 CXTUResourceUsage usage = { (void*) entries.get(),
7637 (unsigned) entries->size(),
Alexander Kornienko6ee521c2015-01-23 15:36:10 +00007638 !entries->empty() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00007639 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00007640 return usage;
7641}
7642
7643void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
7644 if (usage.data)
7645 delete (MemUsageEntries*) usage.data;
7646}
7647
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007648CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
7649 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007650 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00007651 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007652
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007653 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007654 LOG_BAD_TU(TU);
7655 return skipped;
7656 }
7657
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007658 if (!file)
7659 return skipped;
7660
7661 ASTUnit *astUnit = cxtu::getASTUnit(TU);
7662 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
7663 if (!ppRec)
7664 return skipped;
7665
7666 ASTContext &Ctx = astUnit->getASTContext();
7667 SourceManager &sm = Ctx.getSourceManager();
7668 FileEntry *fileEntry = static_cast<FileEntry *>(file);
7669 FileID wantedFileID = sm.translateFile(fileEntry);
7670
7671 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
7672 std::vector<SourceRange> wantedRanges;
7673 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
7674 i != ei; ++i) {
7675 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
7676 wantedRanges.push_back(*i);
7677 }
7678
7679 skipped->count = wantedRanges.size();
7680 skipped->ranges = new CXSourceRange[skipped->count];
7681 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
7682 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
7683
7684 return skipped;
7685}
7686
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007687void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
7688 if (ranges) {
7689 delete[] ranges->ranges;
7690 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007691 }
7692}
7693
Guy Benyei11169dd2012-12-18 14:30:41 +00007694} // end extern "C"
7695
7696void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
7697 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
7698 for (unsigned I = 0; I != Usage.numEntries; ++I)
7699 fprintf(stderr, " %s: %lu\n",
7700 clang_getTUResourceUsageName(Usage.entries[I].kind),
7701 Usage.entries[I].amount);
7702
7703 clang_disposeCXTUResourceUsage(Usage);
7704}
7705
7706//===----------------------------------------------------------------------===//
7707// Misc. utility functions.
7708//===----------------------------------------------------------------------===//
7709
7710/// Default to using an 8 MB stack size on "safety" threads.
7711static unsigned SafetyStackThreadSize = 8 << 20;
7712
7713namespace clang {
7714
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007715bool RunSafely(llvm::CrashRecoveryContext &CRC, llvm::function_ref<void()> Fn,
Guy Benyei11169dd2012-12-18 14:30:41 +00007716 unsigned Size) {
7717 if (!Size)
7718 Size = GetSafetyThreadStackSize();
7719 if (Size)
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007720 return CRC.RunSafelyOnThread(Fn, Size);
7721 return CRC.RunSafely(Fn);
Guy Benyei11169dd2012-12-18 14:30:41 +00007722}
7723
7724unsigned GetSafetyThreadStackSize() {
7725 return SafetyStackThreadSize;
7726}
7727
7728void SetSafetyThreadStackSize(unsigned Value) {
7729 SafetyStackThreadSize = Value;
7730}
7731
Alexander Kornienkoab9db512015-06-22 23:07:51 +00007732}
Guy Benyei11169dd2012-12-18 14:30:41 +00007733
7734void clang::setThreadBackgroundPriority() {
7735 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
7736 return;
7737
Alp Toker1a86ad22014-07-06 06:24:00 +00007738#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00007739 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
7740#endif
7741}
7742
7743void cxindex::printDiagsToStderr(ASTUnit *Unit) {
7744 if (!Unit)
7745 return;
7746
7747 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
7748 DEnd = Unit->stored_diag_end();
7749 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00007750 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00007751 CXString Msg = clang_formatDiagnostic(&Diag,
7752 clang_defaultDiagnosticDisplayOptions());
7753 fprintf(stderr, "%s\n", clang_getCString(Msg));
7754 clang_disposeString(Msg);
7755 }
7756#ifdef LLVM_ON_WIN32
7757 // On Windows, force a flush, since there may be multiple copies of
7758 // stderr and stdout in the file system, all with different buffers
7759 // but writing to the same device.
7760 fflush(stderr);
7761#endif
7762}
7763
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007764MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
7765 SourceLocation MacroDefLoc,
7766 CXTranslationUnit TU){
7767 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007768 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007769 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007770 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007771
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007772 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007773 Preprocessor &PP = Unit->getPreprocessor();
Richard Smith20e883e2015-04-29 23:20:19 +00007774 MacroDirective *MD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007775 if (MD) {
7776 for (MacroDirective::DefInfo
7777 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
7778 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
7779 return Def.getMacroInfo();
7780 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007781 }
7782
Craig Topper69186e72014-06-08 08:38:04 +00007783 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007784}
7785
Richard Smith66a81862015-05-04 02:25:31 +00007786const MacroInfo *cxindex::getMacroInfo(const MacroDefinitionRecord *MacroDef,
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007787 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007788 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007789 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007790 const IdentifierInfo *II = MacroDef->getName();
7791 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00007792 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007793
7794 return getMacroInfo(*II, MacroDef->getLocation(), TU);
7795}
7796
Richard Smith66a81862015-05-04 02:25:31 +00007797MacroDefinitionRecord *
7798cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, const Token &Tok,
7799 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007800 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007801 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007802 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00007803 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007804
7805 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007806 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007807 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
7808 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007809 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007810
7811 // Check that the token is inside the definition and not its argument list.
7812 SourceManager &SM = Unit->getSourceManager();
7813 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00007814 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007815 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00007816 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007817
7818 Preprocessor &PP = Unit->getPreprocessor();
7819 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
7820 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00007821 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007822
Alp Toker2d57cea2014-05-17 04:53:25 +00007823 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007824 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007825 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007826
7827 // Check that the identifier is not one of the macro arguments.
7828 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00007829 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007830
Richard Smith20e883e2015-04-29 23:20:19 +00007831 MacroDirective *InnerMD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007832 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00007833 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007834
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007835 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007836}
7837
Richard Smith66a81862015-05-04 02:25:31 +00007838MacroDefinitionRecord *
7839cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, SourceLocation Loc,
7840 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007841 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007842 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007843
7844 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007845 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007846 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007847 Preprocessor &PP = Unit->getPreprocessor();
7848 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00007849 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007850 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7851 Token Tok;
7852 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00007853 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007854
7855 return checkForMacroInMacroDefinition(MI, Tok, TU);
7856}
7857
Guy Benyei11169dd2012-12-18 14:30:41 +00007858extern "C" {
7859
7860CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007861 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00007862}
7863
7864} // end: extern "C"
7865
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007866Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7867 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007868 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007869 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007870 if (Unit->isMainFileAST())
7871 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007872 return *this;
7873 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007874 } else {
7875 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007876 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007877 return *this;
7878}
7879
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007880Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7881 *this << FE->getName();
7882 return *this;
7883}
7884
7885Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7886 CXString cursorName = clang_getCursorDisplayName(cursor);
7887 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7888 clang_disposeString(cursorName);
7889 return *this;
7890}
7891
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007892Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7893 CXFile File;
7894 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007895 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007896 CXString FileName = clang_getFileName(File);
7897 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7898 clang_disposeString(FileName);
7899 return *this;
7900}
7901
7902Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7903 CXSourceLocation BLoc = clang_getRangeStart(range);
7904 CXSourceLocation ELoc = clang_getRangeEnd(range);
7905
7906 CXFile BFile;
7907 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007908 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007909
7910 CXFile EFile;
7911 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007912 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007913
7914 CXString BFileName = clang_getFileName(BFile);
7915 if (BFile == EFile) {
7916 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7917 BLine, BColumn, ELine, EColumn);
7918 } else {
7919 CXString EFileName = clang_getFileName(EFile);
7920 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7921 BLine, BColumn)
7922 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7923 ELine, EColumn);
7924 clang_disposeString(EFileName);
7925 }
7926 clang_disposeString(BFileName);
7927 return *this;
7928}
7929
7930Logger &cxindex::Logger::operator<<(CXString Str) {
7931 *this << clang_getCString(Str);
7932 return *this;
7933}
7934
7935Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7936 LogOS << Fmt;
7937 return *this;
7938}
7939
Chandler Carruth37ad2582014-06-27 15:14:39 +00007940static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7941
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007942cxindex::Logger::~Logger() {
Chandler Carruth37ad2582014-06-27 15:14:39 +00007943 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007944
7945 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7946
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007947 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007948 OS << "[libclang:" << Name << ':';
7949
Alp Toker1a86ad22014-07-06 06:24:00 +00007950#ifdef USE_DARWIN_THREADS
7951 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007952 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7953 OS << tid << ':';
7954#endif
7955
7956 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7957 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
Yaron Keren09fb7c62015-03-10 07:33:23 +00007958 OS << Msg << '\n';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007959
7960 if (Trace) {
Zachary Turner1fe2a8d2015-03-05 19:15:09 +00007961 llvm::sys::PrintStackTrace(OS);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007962 OS << "--------------------------------------------------\n";
7963 }
7964}