blob: 18851a0dd8b7884300d2370d01b52be4741f26cc [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);
Alexey Bataev13314bf2014-10-09 04:18:56 +00001956 void VisitOMPTeamsDirective(const OMPTeamsDirective *D);
Alexey Bataev49f6e782015-12-01 04:18:41 +00001957 void VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *D);
Alexey Bataev0a6ed842015-12-03 09:40:15 +00001958 void VisitOMPTaskLoopSimdDirective(const OMPTaskLoopSimdDirective *D);
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00001959 void VisitOMPDistributeDirective(const OMPDistributeDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001960
Guy Benyei11169dd2012-12-18 14:30:41 +00001961private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001962 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001963 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
James Y Knight04ec5bf2015-12-24 02:59:37 +00001964 void AddExplicitTemplateArgs(const TemplateArgumentLoc *A,
1965 unsigned NumTemplateArgs);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001966 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1967 void AddStmt(const Stmt *S);
1968 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001969 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001970 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001971 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001972};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00001973} // end anonyous namespace
Guy Benyei11169dd2012-12-18 14:30:41 +00001974
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001975void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001976 // 'S' should always be non-null, since it comes from the
1977 // statement we are visiting.
1978 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1979}
1980
1981void
1982EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1983 if (Qualifier)
1984 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1985}
1986
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001987void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001988 if (S)
1989 WL.push_back(StmtVisit(S, Parent));
1990}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001991void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001992 if (D)
1993 WL.push_back(DeclVisit(D, Parent, isFirst));
1994}
James Y Knight04ec5bf2015-12-24 02:59:37 +00001995void EnqueueVisitor::AddExplicitTemplateArgs(const TemplateArgumentLoc *A,
1996 unsigned NumTemplateArgs) {
1997 WL.push_back(ExplicitTemplateArgsVisit(A, A + NumTemplateArgs, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001998}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001999void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002000 if (D)
2001 WL.push_back(MemberRefVisit(D, L, Parent));
2002}
2003void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
2004 if (TI)
2005 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
2006 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002007void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002008 unsigned size = WL.size();
Benjamin Kramer642f1732015-07-02 21:03:14 +00002009 for (const Stmt *SubStmt : S->children()) {
2010 AddStmt(SubStmt);
Guy Benyei11169dd2012-12-18 14:30:41 +00002011 }
2012 if (size == WL.size())
2013 return;
2014 // Now reverse the entries we just added. This will match the DFS
2015 // ordering performed by the worklist.
2016 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2017 std::reverse(I, E);
2018}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002019namespace {
2020class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
2021 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00002022 /// \brief Process clauses with list of variables.
2023 template <typename T>
2024 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002025public:
2026 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
2027#define OPENMP_CLAUSE(Name, Class) \
2028 void Visit##Class(const Class *C);
2029#include "clang/Basic/OpenMPKinds.def"
2030};
2031
Alexey Bataevaadd52e2014-02-13 05:29:23 +00002032void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
2033 Visitor->AddStmt(C->getCondition());
2034}
2035
Alexey Bataev3778b602014-07-17 07:32:53 +00002036void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
2037 Visitor->AddStmt(C->getCondition());
2038}
2039
Alexey Bataev568a8332014-03-06 06:15:19 +00002040void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
2041 Visitor->AddStmt(C->getNumThreads());
2042}
2043
Alexey Bataev62c87d22014-03-21 04:51:18 +00002044void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
2045 Visitor->AddStmt(C->getSafelen());
2046}
2047
Alexey Bataev66b15b52015-08-21 11:14:16 +00002048void OMPClauseEnqueue::VisitOMPSimdlenClause(const OMPSimdlenClause *C) {
2049 Visitor->AddStmt(C->getSimdlen());
2050}
2051
Alexander Musman8bd31e62014-05-27 15:12:19 +00002052void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
2053 Visitor->AddStmt(C->getNumForLoops());
2054}
2055
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002056void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00002057
Alexey Bataevbcbadb62014-05-06 06:04:14 +00002058void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
2059
Alexey Bataev56dafe82014-06-20 07:16:17 +00002060void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
2061 Visitor->AddStmt(C->getChunkSize());
Alexey Bataev040d5402015-05-12 08:35:28 +00002062 Visitor->AddStmt(C->getHelperChunkSize());
Alexey Bataev56dafe82014-06-20 07:16:17 +00002063}
2064
Alexey Bataev10e775f2015-07-30 11:36:16 +00002065void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *C) {
2066 Visitor->AddStmt(C->getNumForLoops());
2067}
Alexey Bataev142e1fc2014-06-20 09:44:06 +00002068
Alexey Bataev236070f2014-06-20 11:19:47 +00002069void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
2070
Alexey Bataev7aea99a2014-07-17 12:19:31 +00002071void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
2072
Alexey Bataev74ba3a52014-07-17 12:47:03 +00002073void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
2074
Alexey Bataevf98b00c2014-07-23 02:27:21 +00002075void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}
2076
Alexey Bataevdea47612014-07-23 07:46:59 +00002077void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {}
2078
Alexey Bataev67a4f222014-07-23 10:25:33 +00002079void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {}
2080
Alexey Bataev459dec02014-07-24 06:46:57 +00002081void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}
2082
Alexey Bataev82bad8b2014-07-24 08:55:34 +00002083void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
2084
Alexey Bataev346265e2015-09-25 10:37:12 +00002085void OMPClauseEnqueue::VisitOMPThreadsClause(const OMPThreadsClause *) {}
2086
Alexey Bataevd14d1e62015-09-28 06:39:35 +00002087void OMPClauseEnqueue::VisitOMPSIMDClause(const OMPSIMDClause *) {}
2088
Alexey Bataevb825de12015-12-07 10:51:44 +00002089void OMPClauseEnqueue::VisitOMPNogroupClause(const OMPNogroupClause *) {}
2090
Michael Wonge710d542015-08-07 16:16:36 +00002091void OMPClauseEnqueue::VisitOMPDeviceClause(const OMPDeviceClause *C) {
2092 Visitor->AddStmt(C->getDevice());
2093}
2094
Kelvin Li099bb8c2015-11-24 20:50:12 +00002095void OMPClauseEnqueue::VisitOMPNumTeamsClause(const OMPNumTeamsClause *C) {
2096 Visitor->AddStmt(C->getNumTeams());
2097}
2098
Kelvin Lia15fb1a2015-11-27 18:47:36 +00002099void OMPClauseEnqueue::VisitOMPThreadLimitClause(const OMPThreadLimitClause *C) {
2100 Visitor->AddStmt(C->getThreadLimit());
2101}
2102
Alexey Bataeva0569352015-12-01 10:17:31 +00002103void OMPClauseEnqueue::VisitOMPPriorityClause(const OMPPriorityClause *C) {
2104 Visitor->AddStmt(C->getPriority());
2105}
2106
Alexey Bataev1fd4aed2015-12-07 12:52:51 +00002107void OMPClauseEnqueue::VisitOMPGrainsizeClause(const OMPGrainsizeClause *C) {
2108 Visitor->AddStmt(C->getGrainsize());
2109}
2110
Alexey Bataev382967a2015-12-08 12:06:20 +00002111void OMPClauseEnqueue::VisitOMPNumTasksClause(const OMPNumTasksClause *C) {
2112 Visitor->AddStmt(C->getNumTasks());
2113}
2114
Alexey Bataev28c75412015-12-15 08:19:24 +00002115void OMPClauseEnqueue::VisitOMPHintClause(const OMPHintClause *C) {
2116 Visitor->AddStmt(C->getHint());
2117}
2118
Alexey Bataev756c1962013-09-24 03:17:45 +00002119template<typename T>
2120void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Alexey Bataev03b340a2014-10-21 03:16:40 +00002121 for (const auto *I : Node->varlists()) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00002122 Visitor->AddStmt(I);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002123 }
Alexey Bataev756c1962013-09-24 03:17:45 +00002124}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002125
2126void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002127 VisitOMPClauseList(C);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002128 for (const auto *E : C->private_copies()) {
2129 Visitor->AddStmt(E);
2130 }
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002131}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002132void OMPClauseEnqueue::VisitOMPFirstprivateClause(
2133 const OMPFirstprivateClause *C) {
2134 VisitOMPClauseList(C);
2135}
Alexander Musman1bb328c2014-06-04 13:06:39 +00002136void OMPClauseEnqueue::VisitOMPLastprivateClause(
2137 const OMPLastprivateClause *C) {
2138 VisitOMPClauseList(C);
Alexey Bataev38e89532015-04-16 04:54:05 +00002139 for (auto *E : C->private_copies()) {
2140 Visitor->AddStmt(E);
2141 }
2142 for (auto *E : C->source_exprs()) {
2143 Visitor->AddStmt(E);
2144 }
2145 for (auto *E : C->destination_exprs()) {
2146 Visitor->AddStmt(E);
2147 }
2148 for (auto *E : C->assignment_ops()) {
2149 Visitor->AddStmt(E);
2150 }
Alexander Musman1bb328c2014-06-04 13:06:39 +00002151}
Alexey Bataev758e55e2013-09-06 18:03:48 +00002152void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002153 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00002154}
Alexey Bataevc5e02582014-06-16 07:08:35 +00002155void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
2156 VisitOMPClauseList(C);
Alexey Bataevf24e7b12015-10-08 09:10:53 +00002157 for (auto *E : C->privates()) {
2158 Visitor->AddStmt(E);
2159 }
Alexey Bataev794ba0d2015-04-10 10:43:45 +00002160 for (auto *E : C->lhs_exprs()) {
2161 Visitor->AddStmt(E);
2162 }
2163 for (auto *E : C->rhs_exprs()) {
2164 Visitor->AddStmt(E);
2165 }
2166 for (auto *E : C->reduction_ops()) {
2167 Visitor->AddStmt(E);
2168 }
Alexey Bataevc5e02582014-06-16 07:08:35 +00002169}
Alexander Musman8dba6642014-04-22 13:09:42 +00002170void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2171 VisitOMPClauseList(C);
Alexey Bataevbd9fec12015-08-18 06:47:21 +00002172 for (const auto *E : C->privates()) {
2173 Visitor->AddStmt(E);
2174 }
Alexander Musman3276a272015-03-21 10:12:56 +00002175 for (const auto *E : C->inits()) {
2176 Visitor->AddStmt(E);
2177 }
2178 for (const auto *E : C->updates()) {
2179 Visitor->AddStmt(E);
2180 }
2181 for (const auto *E : C->finals()) {
2182 Visitor->AddStmt(E);
2183 }
Alexander Musman8dba6642014-04-22 13:09:42 +00002184 Visitor->AddStmt(C->getStep());
Alexander Musman3276a272015-03-21 10:12:56 +00002185 Visitor->AddStmt(C->getCalcStep());
Alexander Musman8dba6642014-04-22 13:09:42 +00002186}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002187void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2188 VisitOMPClauseList(C);
2189 Visitor->AddStmt(C->getAlignment());
2190}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002191void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2192 VisitOMPClauseList(C);
Alexey Bataevf56f98c2015-04-16 05:39:01 +00002193 for (auto *E : C->source_exprs()) {
2194 Visitor->AddStmt(E);
2195 }
2196 for (auto *E : C->destination_exprs()) {
2197 Visitor->AddStmt(E);
2198 }
2199 for (auto *E : C->assignment_ops()) {
2200 Visitor->AddStmt(E);
2201 }
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002202}
Alexey Bataevbae9a792014-06-27 10:37:06 +00002203void
2204OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
2205 VisitOMPClauseList(C);
Alexey Bataeva63048e2015-03-23 06:18:07 +00002206 for (auto *E : C->source_exprs()) {
2207 Visitor->AddStmt(E);
2208 }
2209 for (auto *E : C->destination_exprs()) {
2210 Visitor->AddStmt(E);
2211 }
2212 for (auto *E : C->assignment_ops()) {
2213 Visitor->AddStmt(E);
2214 }
Alexey Bataevbae9a792014-06-27 10:37:06 +00002215}
Alexey Bataev6125da92014-07-21 11:26:11 +00002216void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2217 VisitOMPClauseList(C);
2218}
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +00002219void OMPClauseEnqueue::VisitOMPDependClause(const OMPDependClause *C) {
2220 VisitOMPClauseList(C);
2221}
Kelvin Li0bff7af2015-11-23 05:32:03 +00002222void OMPClauseEnqueue::VisitOMPMapClause(const OMPMapClause *C) {
2223 VisitOMPClauseList(C);
2224}
Carlo Bertollib4adf552016-01-15 18:50:31 +00002225void OMPClauseEnqueue::VisitOMPDistScheduleClause(
2226 const OMPDistScheduleClause *C) {
2227 Visitor->AddStmt(C->getChunkSize());
2228 Visitor->AddStmt(C->getHelperChunkSize());
2229}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002230}
Alexey Bataev756c1962013-09-24 03:17:45 +00002231
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002232void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2233 unsigned size = WL.size();
2234 OMPClauseEnqueue Visitor(this);
2235 Visitor.Visit(S);
2236 if (size == WL.size())
2237 return;
2238 // Now reverse the entries we just added. This will match the DFS
2239 // ordering performed by the worklist.
2240 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2241 std::reverse(I, E);
2242}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002243void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002244 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2245}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002246void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002247 AddDecl(B->getBlockDecl());
2248}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002249void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002250 EnqueueChildren(E);
2251 AddTypeLoc(E->getTypeSourceInfo());
2252}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002253void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
Pete Cooper57d3f142015-07-30 17:22:52 +00002254 for (auto &I : llvm::reverse(S->body()))
2255 AddStmt(I);
Guy Benyei11169dd2012-12-18 14:30:41 +00002256}
2257void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002258VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002259 AddStmt(S->getSubStmt());
2260 AddDeclarationNameInfo(S);
2261 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2262 AddNestedNameSpecifierLoc(QualifierLoc);
2263}
2264
2265void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002266VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002267 if (E->hasExplicitTemplateArgs())
2268 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002269 AddDeclarationNameInfo(E);
2270 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2271 AddNestedNameSpecifierLoc(QualifierLoc);
2272 if (!E->isImplicitAccess())
2273 AddStmt(E->getBase());
2274}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002275void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002276 // Enqueue the initializer , if any.
2277 AddStmt(E->getInitializer());
2278 // Enqueue the array size, if any.
2279 AddStmt(E->getArraySize());
2280 // Enqueue the allocated type.
2281 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2282 // Enqueue the placement arguments.
2283 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2284 AddStmt(E->getPlacementArg(I-1));
2285}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002286void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002287 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2288 AddStmt(CE->getArg(I-1));
2289 AddStmt(CE->getCallee());
2290 AddStmt(CE->getArg(0));
2291}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002292void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2293 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002294 // Visit the name of the type being destroyed.
2295 AddTypeLoc(E->getDestroyedTypeInfo());
2296 // Visit the scope type that looks disturbingly like the nested-name-specifier
2297 // but isn't.
2298 AddTypeLoc(E->getScopeTypeInfo());
2299 // Visit the nested-name-specifier.
2300 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2301 AddNestedNameSpecifierLoc(QualifierLoc);
2302 // Visit base expression.
2303 AddStmt(E->getBase());
2304}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002305void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2306 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002307 AddTypeLoc(E->getTypeSourceInfo());
2308}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002309void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2310 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002311 EnqueueChildren(E);
2312 AddTypeLoc(E->getTypeSourceInfo());
2313}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002314void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002315 EnqueueChildren(E);
2316 if (E->isTypeOperand())
2317 AddTypeLoc(E->getTypeOperandSourceInfo());
2318}
2319
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002320void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2321 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002322 EnqueueChildren(E);
2323 AddTypeLoc(E->getTypeSourceInfo());
2324}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002325void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002326 EnqueueChildren(E);
2327 if (E->isTypeOperand())
2328 AddTypeLoc(E->getTypeOperandSourceInfo());
2329}
2330
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002331void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002332 EnqueueChildren(S);
2333 AddDecl(S->getExceptionDecl());
2334}
2335
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002336void EnqueueVisitor::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002337 AddStmt(S->getBody());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002338 AddStmt(S->getRangeInit());
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002339 AddDecl(S->getLoopVariable());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002340}
2341
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002342void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002343 if (DR->hasExplicitTemplateArgs())
2344 AddExplicitTemplateArgs(DR->getTemplateArgs(), DR->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002345 WL.push_back(DeclRefExprParts(DR, Parent));
2346}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002347void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2348 const DependentScopeDeclRefExpr *E) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002349 if (E->hasExplicitTemplateArgs())
2350 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002351 AddDeclarationNameInfo(E);
2352 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2353}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002354void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002355 unsigned size = WL.size();
2356 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002357 for (const auto *D : S->decls()) {
2358 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002359 isFirst = false;
2360 }
2361 if (size == WL.size())
2362 return;
2363 // Now reverse the entries we just added. This will match the DFS
2364 // ordering performed by the worklist.
2365 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2366 std::reverse(I, E);
2367}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002368void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002369 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002370 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002371 D = E->designators_rbegin(), DEnd = E->designators_rend();
2372 D != DEnd; ++D) {
2373 if (D->isFieldDesignator()) {
2374 if (FieldDecl *Field = D->getField())
2375 AddMemberRef(Field, D->getFieldLoc());
2376 continue;
2377 }
2378 if (D->isArrayDesignator()) {
2379 AddStmt(E->getArrayIndex(*D));
2380 continue;
2381 }
2382 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2383 AddStmt(E->getArrayRangeEnd(*D));
2384 AddStmt(E->getArrayRangeStart(*D));
2385 }
2386}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002387void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002388 EnqueueChildren(E);
2389 AddTypeLoc(E->getTypeInfoAsWritten());
2390}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002391void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002392 AddStmt(FS->getBody());
2393 AddStmt(FS->getInc());
2394 AddStmt(FS->getCond());
2395 AddDecl(FS->getConditionVariable());
2396 AddStmt(FS->getInit());
2397}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002398void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002399 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2400}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002401void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002402 AddStmt(If->getElse());
2403 AddStmt(If->getThen());
2404 AddStmt(If->getCond());
2405 AddDecl(If->getConditionVariable());
2406}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002407void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002408 // We care about the syntactic form of the initializer list, only.
2409 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2410 IE = Syntactic;
2411 EnqueueChildren(IE);
2412}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002413void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002414 WL.push_back(MemberExprParts(M, Parent));
2415
2416 // If the base of the member access expression is an implicit 'this', don't
2417 // visit it.
2418 // FIXME: If we ever want to show these implicit accesses, this will be
2419 // unfortunate. However, clang_getCursor() relies on this behavior.
Argyrios Kyrtzidis58d0e7a2015-03-13 04:40:07 +00002420 if (M->isImplicitAccess())
2421 return;
2422
2423 // Ignore base anonymous struct/union fields, otherwise they will shadow the
2424 // real field that that we are interested in.
2425 if (auto *SubME = dyn_cast<MemberExpr>(M->getBase())) {
2426 if (auto *FD = dyn_cast_or_null<FieldDecl>(SubME->getMemberDecl())) {
2427 if (FD->isAnonymousStructOrUnion()) {
2428 AddStmt(SubME->getBase());
2429 return;
2430 }
2431 }
2432 }
2433
2434 AddStmt(M->getBase());
Guy Benyei11169dd2012-12-18 14:30:41 +00002435}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002436void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002437 AddTypeLoc(E->getEncodedTypeSourceInfo());
2438}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002439void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002440 EnqueueChildren(M);
2441 AddTypeLoc(M->getClassReceiverTypeInfo());
2442}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002443void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002444 // Visit the components of the offsetof expression.
2445 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002446 const OffsetOfNode &Node = E->getComponent(I-1);
2447 switch (Node.getKind()) {
2448 case OffsetOfNode::Array:
2449 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2450 break;
2451 case OffsetOfNode::Field:
2452 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2453 break;
2454 case OffsetOfNode::Identifier:
2455 case OffsetOfNode::Base:
2456 continue;
2457 }
2458 }
2459 // Visit the type into which we're computing the offset.
2460 AddTypeLoc(E->getTypeSourceInfo());
2461}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002462void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002463 if (E->hasExplicitTemplateArgs())
2464 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002465 WL.push_back(OverloadExprParts(E, Parent));
2466}
2467void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002468 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002469 EnqueueChildren(E);
2470 if (E->isArgumentType())
2471 AddTypeLoc(E->getArgumentTypeInfo());
2472}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002473void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002474 EnqueueChildren(S);
2475}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002476void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002477 AddStmt(S->getBody());
2478 AddStmt(S->getCond());
2479 AddDecl(S->getConditionVariable());
2480}
2481
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002482void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002483 AddStmt(W->getBody());
2484 AddStmt(W->getCond());
2485 AddDecl(W->getConditionVariable());
2486}
2487
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002488void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002489 for (unsigned I = E->getNumArgs(); I > 0; --I)
2490 AddTypeLoc(E->getArg(I-1));
2491}
2492
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002493void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002494 AddTypeLoc(E->getQueriedTypeSourceInfo());
2495}
2496
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002497void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002498 EnqueueChildren(E);
2499}
2500
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002501void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002502 VisitOverloadExpr(U);
2503 if (!U->isImplicitAccess())
2504 AddStmt(U->getBase());
2505}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002506void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002507 AddStmt(E->getSubExpr());
2508 AddTypeLoc(E->getWrittenTypeInfo());
2509}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002510void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002511 WL.push_back(SizeOfPackExprParts(E, Parent));
2512}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002513void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002514 // If the opaque value has a source expression, just transparently
2515 // visit that. This is useful for (e.g.) pseudo-object expressions.
2516 if (Expr *SourceExpr = E->getSourceExpr())
2517 return Visit(SourceExpr);
2518}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002519void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002520 AddStmt(E->getBody());
2521 WL.push_back(LambdaExprParts(E, Parent));
2522}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002523void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002524 // Treat the expression like its syntactic form.
2525 Visit(E->getSyntacticForm());
2526}
2527
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002528void EnqueueVisitor::VisitOMPExecutableDirective(
2529 const OMPExecutableDirective *D) {
2530 EnqueueChildren(D);
2531 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2532 E = D->clauses().end();
2533 I != E; ++I)
2534 EnqueueChildren(*I);
2535}
2536
Alexander Musman3aaab662014-08-19 11:27:13 +00002537void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
2538 VisitOMPExecutableDirective(D);
2539}
2540
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002541void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2542 VisitOMPExecutableDirective(D);
2543}
2544
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002545void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002546 VisitOMPLoopDirective(D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002547}
2548
Alexey Bataevf29276e2014-06-18 04:14:57 +00002549void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002550 VisitOMPLoopDirective(D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002551}
2552
Alexander Musmanf82886e2014-09-18 05:12:34 +00002553void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
2554 VisitOMPLoopDirective(D);
2555}
2556
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002557void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2558 VisitOMPExecutableDirective(D);
2559}
2560
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002561void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2562 VisitOMPExecutableDirective(D);
2563}
2564
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002565void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2566 VisitOMPExecutableDirective(D);
2567}
2568
Alexander Musman80c22892014-07-17 08:54:58 +00002569void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2570 VisitOMPExecutableDirective(D);
2571}
2572
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002573void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2574 VisitOMPExecutableDirective(D);
2575 AddDeclarationNameInfo(D);
2576}
2577
Alexey Bataev4acb8592014-07-07 13:01:15 +00002578void
2579EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002580 VisitOMPLoopDirective(D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002581}
2582
Alexander Musmane4e893b2014-09-23 09:33:00 +00002583void EnqueueVisitor::VisitOMPParallelForSimdDirective(
2584 const OMPParallelForSimdDirective *D) {
2585 VisitOMPLoopDirective(D);
2586}
2587
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002588void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2589 const OMPParallelSectionsDirective *D) {
2590 VisitOMPExecutableDirective(D);
2591}
2592
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002593void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2594 VisitOMPExecutableDirective(D);
2595}
2596
Alexey Bataev68446b72014-07-18 07:47:19 +00002597void
2598EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2599 VisitOMPExecutableDirective(D);
2600}
2601
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002602void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2603 VisitOMPExecutableDirective(D);
2604}
2605
Alexey Bataev2df347a2014-07-18 10:17:07 +00002606void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2607 VisitOMPExecutableDirective(D);
2608}
2609
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002610void EnqueueVisitor::VisitOMPTaskgroupDirective(
2611 const OMPTaskgroupDirective *D) {
2612 VisitOMPExecutableDirective(D);
2613}
2614
Alexey Bataev6125da92014-07-21 11:26:11 +00002615void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2616 VisitOMPExecutableDirective(D);
2617}
2618
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002619void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2620 VisitOMPExecutableDirective(D);
2621}
2622
Alexey Bataev0162e452014-07-22 10:10:35 +00002623void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2624 VisitOMPExecutableDirective(D);
2625}
2626
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002627void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
2628 VisitOMPExecutableDirective(D);
2629}
2630
Michael Wong65f367f2015-07-21 13:44:28 +00002631void EnqueueVisitor::VisitOMPTargetDataDirective(const
2632 OMPTargetDataDirective *D) {
2633 VisitOMPExecutableDirective(D);
2634}
2635
Alexey Bataev13314bf2014-10-09 04:18:56 +00002636void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {
2637 VisitOMPExecutableDirective(D);
2638}
2639
Alexey Bataev6d4ed052015-07-01 06:57:41 +00002640void EnqueueVisitor::VisitOMPCancellationPointDirective(
2641 const OMPCancellationPointDirective *D) {
2642 VisitOMPExecutableDirective(D);
2643}
2644
Alexey Bataev80909872015-07-02 11:25:17 +00002645void EnqueueVisitor::VisitOMPCancelDirective(const OMPCancelDirective *D) {
2646 VisitOMPExecutableDirective(D);
2647}
2648
Alexey Bataev49f6e782015-12-01 04:18:41 +00002649void EnqueueVisitor::VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *D) {
2650 VisitOMPLoopDirective(D);
2651}
2652
Alexey Bataev0a6ed842015-12-03 09:40:15 +00002653void EnqueueVisitor::VisitOMPTaskLoopSimdDirective(
2654 const OMPTaskLoopSimdDirective *D) {
2655 VisitOMPLoopDirective(D);
2656}
2657
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00002658void EnqueueVisitor::VisitOMPDistributeDirective(
2659 const OMPDistributeDirective *D) {
2660 VisitOMPLoopDirective(D);
2661}
2662
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002663void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002664 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2665}
2666
2667bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2668 if (RegionOfInterest.isValid()) {
2669 SourceRange Range = getRawCursorExtent(C);
2670 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2671 return false;
2672 }
2673 return true;
2674}
2675
2676bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2677 while (!WL.empty()) {
2678 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002679 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002680
2681 // Set the Parent field, then back to its old value once we're done.
2682 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2683
2684 switch (LI.getKind()) {
2685 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002686 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002687 if (!D)
2688 continue;
2689
2690 // For now, perform default visitation for Decls.
2691 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2692 cast<DeclVisit>(&LI)->isFirst())))
2693 return true;
2694
2695 continue;
2696 }
2697 case VisitorJob::ExplicitTemplateArgsVisitKind: {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002698 for (const TemplateArgumentLoc &Arg :
2699 *cast<ExplicitTemplateArgsVisit>(&LI)) {
2700 if (VisitTemplateArgumentLoc(Arg))
Guy Benyei11169dd2012-12-18 14:30:41 +00002701 return true;
2702 }
2703 continue;
2704 }
2705 case VisitorJob::TypeLocVisitKind: {
2706 // Perform default visitation for TypeLocs.
2707 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2708 return true;
2709 continue;
2710 }
2711 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002712 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002713 if (LabelStmt *stmt = LS->getStmt()) {
2714 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2715 TU))) {
2716 return true;
2717 }
2718 }
2719 continue;
2720 }
2721
2722 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2723 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2724 if (VisitNestedNameSpecifierLoc(V->get()))
2725 return true;
2726 continue;
2727 }
2728
2729 case VisitorJob::DeclarationNameInfoVisitKind: {
2730 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2731 ->get()))
2732 return true;
2733 continue;
2734 }
2735 case VisitorJob::MemberRefVisitKind: {
2736 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2737 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2738 return true;
2739 continue;
2740 }
2741 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002742 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002743 if (!S)
2744 continue;
2745
2746 // Update the current cursor.
2747 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2748 if (!IsInRegionOfInterest(Cursor))
2749 continue;
2750 switch (Visitor(Cursor, Parent, ClientData)) {
2751 case CXChildVisit_Break: return true;
2752 case CXChildVisit_Continue: break;
2753 case CXChildVisit_Recurse:
2754 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002755 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002756 EnqueueWorkList(WL, S);
2757 break;
2758 }
2759 continue;
2760 }
2761 case VisitorJob::MemberExprPartsKind: {
2762 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002763 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002764
2765 // Visit the nested-name-specifier
2766 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2767 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2768 return true;
2769
2770 // Visit the declaration name.
2771 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2772 return true;
2773
2774 // Visit the explicitly-specified template arguments, if any.
2775 if (M->hasExplicitTemplateArgs()) {
2776 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2777 *ArgEnd = Arg + M->getNumTemplateArgs();
2778 Arg != ArgEnd; ++Arg) {
2779 if (VisitTemplateArgumentLoc(*Arg))
2780 return true;
2781 }
2782 }
2783 continue;
2784 }
2785 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002786 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002787 // Visit nested-name-specifier, if present.
2788 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2789 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2790 return true;
2791 // Visit declaration name.
2792 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2793 return true;
2794 continue;
2795 }
2796 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002797 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002798 // Visit the nested-name-specifier.
2799 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2800 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2801 return true;
2802 // Visit the declaration name.
2803 if (VisitDeclarationNameInfo(O->getNameInfo()))
2804 return true;
2805 // Visit the overloaded declaration reference.
2806 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2807 return true;
2808 continue;
2809 }
2810 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002811 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002812 NamedDecl *Pack = E->getPack();
2813 if (isa<TemplateTypeParmDecl>(Pack)) {
2814 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2815 E->getPackLoc(), TU)))
2816 return true;
2817
2818 continue;
2819 }
2820
2821 if (isa<TemplateTemplateParmDecl>(Pack)) {
2822 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2823 E->getPackLoc(), TU)))
2824 return true;
2825
2826 continue;
2827 }
2828
2829 // Non-type template parameter packs and function parameter packs are
2830 // treated like DeclRefExpr cursors.
2831 continue;
2832 }
2833
2834 case VisitorJob::LambdaExprPartsKind: {
2835 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002836 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002837 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2838 CEnd = E->explicit_capture_end();
2839 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002840 // FIXME: Lambda init-captures.
2841 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002842 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002843
Guy Benyei11169dd2012-12-18 14:30:41 +00002844 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2845 C->getLocation(),
2846 TU)))
2847 return true;
2848 }
2849
2850 // Visit parameters and return type, if present.
2851 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2852 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2853 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2854 // Visit the whole type.
2855 if (Visit(TL))
2856 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002857 } else if (FunctionProtoTypeLoc Proto =
2858 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002859 if (E->hasExplicitParameters()) {
2860 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002861 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2862 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002863 return true;
2864 } else {
2865 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002866 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002867 return true;
2868 }
2869 }
2870 }
2871 break;
2872 }
2873
2874 case VisitorJob::PostChildrenVisitKind:
2875 if (PostChildrenVisitor(Parent, ClientData))
2876 return true;
2877 break;
2878 }
2879 }
2880 return false;
2881}
2882
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002883bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002884 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002885 if (!WorkListFreeList.empty()) {
2886 WL = WorkListFreeList.back();
2887 WL->clear();
2888 WorkListFreeList.pop_back();
2889 }
2890 else {
2891 WL = new VisitorWorkList();
2892 WorkListCache.push_back(WL);
2893 }
2894 EnqueueWorkList(*WL, S);
2895 bool result = RunVisitorWorkList(*WL);
2896 WorkListFreeList.push_back(WL);
2897 return result;
2898}
2899
2900namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002901typedef SmallVector<SourceRange, 4> RefNamePieces;
James Y Knight04ec5bf2015-12-24 02:59:37 +00002902RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2903 const DeclarationNameInfo &NI, SourceRange QLoc,
2904 const SourceRange *TemplateArgsLoc = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002905 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2906 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2907 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2908
2909 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2910
2911 RefNamePieces Pieces;
2912
2913 if (WantQualifier && QLoc.isValid())
2914 Pieces.push_back(QLoc);
2915
2916 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2917 Pieces.push_back(NI.getLoc());
James Y Knight04ec5bf2015-12-24 02:59:37 +00002918
2919 if (WantTemplateArgs && TemplateArgsLoc && TemplateArgsLoc->isValid())
2920 Pieces.push_back(*TemplateArgsLoc);
2921
Guy Benyei11169dd2012-12-18 14:30:41 +00002922 if (Kind == DeclarationName::CXXOperatorName) {
2923 Pieces.push_back(SourceLocation::getFromRawEncoding(
2924 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2925 Pieces.push_back(SourceLocation::getFromRawEncoding(
2926 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2927 }
2928
2929 if (WantSinglePiece) {
2930 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2931 Pieces.clear();
2932 Pieces.push_back(R);
2933 }
2934
2935 return Pieces;
2936}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002937}
Guy Benyei11169dd2012-12-18 14:30:41 +00002938
2939//===----------------------------------------------------------------------===//
2940// Misc. API hooks.
2941//===----------------------------------------------------------------------===//
2942
Chad Rosier05c71aa2013-03-27 18:28:23 +00002943static void fatal_error_handler(void *user_data, const std::string& reason,
2944 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002945 // Write the result out to stderr avoiding errs() because raw_ostreams can
2946 // call report_fatal_error.
2947 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2948 ::abort();
2949}
2950
Chandler Carruth66660742014-06-27 16:37:27 +00002951namespace {
2952struct RegisterFatalErrorHandler {
2953 RegisterFatalErrorHandler() {
2954 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2955 }
2956};
2957}
2958
2959static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
2960
Guy Benyei11169dd2012-12-18 14:30:41 +00002961extern "C" {
2962CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2963 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002964 // We use crash recovery to make some of our APIs more reliable, implicitly
2965 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002966 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2967 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002968
Chandler Carruth66660742014-06-27 16:37:27 +00002969 // Look through the managed static to trigger construction of the managed
2970 // static which registers our fatal error handler. This ensures it is only
2971 // registered once.
2972 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00002973
Adrian Prantlbc068582015-07-08 01:00:30 +00002974 // Initialize targets for clang module support.
2975 llvm::InitializeAllTargets();
2976 llvm::InitializeAllTargetMCs();
2977 llvm::InitializeAllAsmPrinters();
2978 llvm::InitializeAllAsmParsers();
2979
Adrian Prantlfb2398d2015-07-17 01:19:54 +00002980 CIndexer *CIdxr = new CIndexer();
2981
Guy Benyei11169dd2012-12-18 14:30:41 +00002982 if (excludeDeclarationsFromPCH)
2983 CIdxr->setOnlyLocalDecls();
2984 if (displayDiagnostics)
2985 CIdxr->setDisplayDiagnostics();
2986
2987 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2988 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2989 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2990 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2991 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2992 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2993
2994 return CIdxr;
2995}
2996
2997void clang_disposeIndex(CXIndex CIdx) {
2998 if (CIdx)
2999 delete static_cast<CIndexer *>(CIdx);
3000}
3001
3002void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
3003 if (CIdx)
3004 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
3005}
3006
3007unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
3008 if (CIdx)
3009 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
3010 return 0;
3011}
3012
3013void clang_toggleCrashRecovery(unsigned isEnabled) {
3014 if (isEnabled)
3015 llvm::CrashRecoveryContext::Enable();
3016 else
3017 llvm::CrashRecoveryContext::Disable();
3018}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003019
Guy Benyei11169dd2012-12-18 14:30:41 +00003020CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
3021 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003022 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003023 enum CXErrorCode Result =
3024 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00003025 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003026 assert((TU && Result == CXError_Success) ||
3027 (!TU && Result != CXError_Success));
3028 return TU;
3029}
3030
3031enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
3032 const char *ast_filename,
3033 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003034 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00003035 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003036
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003037 if (!CIdx || !ast_filename || !out_TU)
3038 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00003039
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00003040 LOG_FUNC_SECTION {
3041 *Log << ast_filename;
3042 }
3043
Guy Benyei11169dd2012-12-18 14:30:41 +00003044 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3045 FileSystemOptions FileSystemOpts;
3046
Justin Bognerd512c1e2014-10-15 00:33:06 +00003047 IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
3048 CompilerInstance::createDiagnostics(new DiagnosticOptions());
David Blaikie6f7382d2014-08-10 19:08:04 +00003049 std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
Adrian Prantlfb2398d2015-07-17 01:19:54 +00003050 ast_filename, CXXIdx->getPCHContainerOperations()->getRawReader(), Diags,
Adrian Prantl6b21ab22015-08-27 19:46:20 +00003051 FileSystemOpts, /*UseDebugInfo=*/false,
3052 CXXIdx->getOnlyLocalDecls(), None,
David Blaikie6f7382d2014-08-10 19:08:04 +00003053 /*CaptureDiagnostics=*/true,
3054 /*AllowPCHWithCompilerErrors=*/true,
3055 /*UserFilesAreVolatile=*/true);
3056 *out_TU = MakeCXTranslationUnit(CXXIdx, AU.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003057 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003058}
3059
3060unsigned clang_defaultEditingTranslationUnitOptions() {
3061 return CXTranslationUnit_PrecompiledPreamble |
3062 CXTranslationUnit_CacheCompletionResults;
3063}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003064
Guy Benyei11169dd2012-12-18 14:30:41 +00003065CXTranslationUnit
3066clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
3067 const char *source_filename,
3068 int num_command_line_args,
3069 const char * const *command_line_args,
3070 unsigned num_unsaved_files,
3071 struct CXUnsavedFile *unsaved_files) {
3072 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
3073 return clang_parseTranslationUnit(CIdx, source_filename,
3074 command_line_args, num_command_line_args,
3075 unsaved_files, num_unsaved_files,
3076 Options);
3077}
3078
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003079static CXErrorCode
3080clang_parseTranslationUnit_Impl(CXIndex CIdx, const char *source_filename,
3081 const char *const *command_line_args,
3082 int num_command_line_args,
3083 ArrayRef<CXUnsavedFile> unsaved_files,
3084 unsigned options, CXTranslationUnit *out_TU) {
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003085 // Set up the initial return values.
3086 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00003087 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003088
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003089 // Check arguments.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003090 if (!CIdx || !out_TU)
3091 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003092
Guy Benyei11169dd2012-12-18 14:30:41 +00003093 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3094
3095 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3096 setThreadBackgroundPriority();
3097
3098 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
Benjamin Kramer5c248d82015-12-15 09:30:31 +00003099 bool CreatePreambleOnFirstParse =
3100 options & CXTranslationUnit_CreatePreambleOnFirstParse;
Guy Benyei11169dd2012-12-18 14:30:41 +00003101 // FIXME: Add a flag for modules.
3102 TranslationUnitKind TUKind
3103 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00003104 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00003105 = options & CXTranslationUnit_CacheCompletionResults;
3106 bool IncludeBriefCommentsInCodeCompletion
3107 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
3108 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
3109 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
3110
3111 // Configure the diagnostics.
3112 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00003113 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00003114
3115 // Recover resources if we crash before exiting this function.
3116 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
3117 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00003118 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00003119
Ahmed Charlesb8984322014-03-07 20:03:18 +00003120 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3121 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003122
3123 // Recover resources if we crash before exiting this function.
3124 llvm::CrashRecoveryContextCleanupRegistrar<
3125 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3126
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003127 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003128 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003129 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003130 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003131 }
3132
Ahmed Charlesb8984322014-03-07 20:03:18 +00003133 std::unique_ptr<std::vector<const char *>> Args(
3134 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003135
3136 // Recover resources if we crash before exiting this method.
3137 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
3138 ArgsCleanup(Args.get());
3139
3140 // Since the Clang C library is primarily used by batch tools dealing with
3141 // (often very broken) source code, where spell-checking can have a
3142 // significant negative impact on performance (particularly when
3143 // precompiled headers are involved), we disable it by default.
3144 // Only do this if we haven't found a spell-checking-related argument.
3145 bool FoundSpellCheckingArgument = false;
3146 for (int I = 0; I != num_command_line_args; ++I) {
3147 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
3148 strcmp(command_line_args[I], "-fspell-checking") == 0) {
3149 FoundSpellCheckingArgument = true;
3150 break;
3151 }
3152 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003153 Args->insert(Args->end(), command_line_args,
3154 command_line_args + num_command_line_args);
3155
Benjamin Kramerc02670e2015-11-18 16:14:27 +00003156 if (!FoundSpellCheckingArgument)
3157 Args->insert(Args->begin() + 1, "-fno-spell-checking");
3158
Guy Benyei11169dd2012-12-18 14:30:41 +00003159 // The 'source_filename' argument is optional. If the caller does not
3160 // specify it then it is assumed that the source file is specified
3161 // in the actual argument list.
3162 // Put the source file after command_line_args otherwise if '-x' flag is
3163 // present it will be unused.
3164 if (source_filename)
3165 Args->push_back(source_filename);
3166
3167 // Do we need the detailed preprocessing record?
3168 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
3169 Args->push_back("-Xclang");
3170 Args->push_back("-detailed-preprocessing-record");
3171 }
3172
3173 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00003174 std::unique_ptr<ASTUnit> ErrUnit;
Benjamin Kramer5c248d82015-12-15 09:30:31 +00003175 // Unless the user specified that they want the preamble on the first parse
3176 // set it up to be created on the first reparse. This makes the first parse
3177 // faster, trading for a slower (first) reparse.
3178 unsigned PrecompilePreambleAfterNParses =
3179 !PrecompilePreamble ? 0 : 2 - CreatePreambleOnFirstParse;
Ahmed Charlesb8984322014-03-07 20:03:18 +00003180 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003181 Args->data(), Args->data() + Args->size(),
3182 CXXIdx->getPCHContainerOperations(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00003183 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
3184 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
Benjamin Kramer5c248d82015-12-15 09:30:31 +00003185 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreambleAfterNParses,
3186 TUKind, CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
Ahmed Charlesb8984322014-03-07 20:03:18 +00003187 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
Argyrios Kyrtzidisa3e2ff12015-11-20 03:36:21 +00003188 /*UserFilesAreVolatile=*/true, ForSerialization,
3189 CXXIdx->getPCHContainerOperations()->getRawReader().getFormat(),
3190 &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00003191
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003192 // Early failures in LoadFromCommandLine may return with ErrUnit unset.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003193 if (!Unit && !ErrUnit)
3194 return CXError_ASTReadError;
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003195
Guy Benyei11169dd2012-12-18 14:30:41 +00003196 if (NumErrors != Diags->getClient()->getNumErrors()) {
3197 // Make sure to check that 'Unit' is non-NULL.
3198 if (CXXIdx->getDisplayDiagnostics())
3199 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
3200 }
3201
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003202 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get()))
3203 return CXError_ASTReadError;
3204
3205 *out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
3206 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003207}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003208
3209CXTranslationUnit
3210clang_parseTranslationUnit(CXIndex CIdx,
3211 const char *source_filename,
3212 const char *const *command_line_args,
3213 int num_command_line_args,
3214 struct CXUnsavedFile *unsaved_files,
3215 unsigned num_unsaved_files,
3216 unsigned options) {
3217 CXTranslationUnit TU;
3218 enum CXErrorCode Result = clang_parseTranslationUnit2(
3219 CIdx, source_filename, command_line_args, num_command_line_args,
3220 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00003221 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003222 assert((TU && Result == CXError_Success) ||
3223 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003224 return TU;
3225}
3226
3227enum CXErrorCode clang_parseTranslationUnit2(
Benjamin Kramerc02670e2015-11-18 16:14:27 +00003228 CXIndex CIdx, const char *source_filename,
3229 const char *const *command_line_args, int num_command_line_args,
3230 struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
3231 unsigned options, CXTranslationUnit *out_TU) {
3232 SmallVector<const char *, 4> Args;
3233 Args.push_back("clang");
3234 Args.append(command_line_args, command_line_args + num_command_line_args);
3235 return clang_parseTranslationUnit2FullArgv(
3236 CIdx, source_filename, Args.data(), Args.size(), unsaved_files,
3237 num_unsaved_files, options, out_TU);
3238}
3239
3240enum CXErrorCode clang_parseTranslationUnit2FullArgv(
3241 CXIndex CIdx, const char *source_filename,
3242 const char *const *command_line_args, int num_command_line_args,
3243 struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
3244 unsigned options, CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003245 LOG_FUNC_SECTION {
3246 *Log << source_filename << ": ";
3247 for (int i = 0; i != num_command_line_args; ++i)
3248 *Log << command_line_args[i] << " ";
3249 }
3250
Alp Toker9d85b182014-07-07 01:23:14 +00003251 if (num_unsaved_files && !unsaved_files)
3252 return CXError_InvalidArguments;
3253
Alp Toker5c532982014-07-07 22:42:03 +00003254 CXErrorCode result = CXError_Failure;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003255 auto ParseTranslationUnitImpl = [=, &result] {
3256 result = clang_parseTranslationUnit_Impl(
3257 CIdx, source_filename, command_line_args, num_command_line_args,
3258 llvm::makeArrayRef(unsaved_files, num_unsaved_files), options, out_TU);
3259 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003260 llvm::CrashRecoveryContext CRC;
3261
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003262 if (!RunSafely(CRC, ParseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003263 fprintf(stderr, "libclang: crash detected during parsing: {\n");
3264 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3265 fprintf(stderr, " 'command_line_args' : [");
3266 for (int i = 0; i != num_command_line_args; ++i) {
3267 if (i)
3268 fprintf(stderr, ", ");
3269 fprintf(stderr, "'%s'", command_line_args[i]);
3270 }
3271 fprintf(stderr, "],\n");
3272 fprintf(stderr, " 'unsaved_files' : [");
3273 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3274 if (i)
3275 fprintf(stderr, ", ");
3276 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3277 unsaved_files[i].Length);
3278 }
3279 fprintf(stderr, "],\n");
3280 fprintf(stderr, " 'options' : %d,\n", options);
3281 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003282
3283 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003284 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003285 if (CXTranslationUnit *TU = out_TU)
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003286 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003287 }
Alp Toker5c532982014-07-07 22:42:03 +00003288
3289 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003290}
3291
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003292CXString clang_Type_getObjCEncoding(CXType CT) {
3293 CXTranslationUnit tu = static_cast<CXTranslationUnit>(CT.data[1]);
3294 ASTContext &Ctx = getASTUnit(tu)->getASTContext();
3295 std::string encoding;
3296 Ctx.getObjCEncodingForType(QualType::getFromOpaquePtr(CT.data[0]),
3297 encoding);
3298
3299 return cxstring::createDup(encoding);
3300}
3301
3302static const IdentifierInfo *getMacroIdentifier(CXCursor C) {
3303 if (C.kind == CXCursor_MacroDefinition) {
3304 if (const MacroDefinitionRecord *MDR = getCursorMacroDefinition(C))
3305 return MDR->getName();
3306 } else if (C.kind == CXCursor_MacroExpansion) {
3307 MacroExpansionCursor ME = getCursorMacroExpansion(C);
3308 return ME.getName();
3309 }
3310 return nullptr;
3311}
3312
3313unsigned clang_Cursor_isMacroFunctionLike(CXCursor C) {
3314 const IdentifierInfo *II = getMacroIdentifier(C);
3315 if (!II) {
3316 return false;
3317 }
3318 ASTUnit *ASTU = getCursorASTUnit(C);
3319 Preprocessor &PP = ASTU->getPreprocessor();
3320 if (const MacroInfo *MI = PP.getMacroInfo(II))
3321 return MI->isFunctionLike();
3322 return false;
3323}
3324
3325unsigned clang_Cursor_isMacroBuiltin(CXCursor C) {
3326 const IdentifierInfo *II = getMacroIdentifier(C);
3327 if (!II) {
3328 return false;
3329 }
3330 ASTUnit *ASTU = getCursorASTUnit(C);
3331 Preprocessor &PP = ASTU->getPreprocessor();
3332 if (const MacroInfo *MI = PP.getMacroInfo(II))
3333 return MI->isBuiltinMacro();
3334 return false;
3335}
3336
3337unsigned clang_Cursor_isFunctionInlined(CXCursor C) {
3338 const Decl *D = getCursorDecl(C);
3339 const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D);
3340 if (!FD) {
3341 return false;
3342 }
3343 return FD->isInlined();
3344}
3345
3346static StringLiteral* getCFSTR_value(CallExpr *callExpr) {
3347 if (callExpr->getNumArgs() != 1) {
3348 return nullptr;
3349 }
3350
3351 StringLiteral *S = nullptr;
3352 auto *arg = callExpr->getArg(0);
3353 if (arg->getStmtClass() == Stmt::ImplicitCastExprClass) {
3354 ImplicitCastExpr *I = static_cast<ImplicitCastExpr *>(arg);
3355 auto *subExpr = I->getSubExprAsWritten();
3356
3357 if(subExpr->getStmtClass() != Stmt::StringLiteralClass){
3358 return nullptr;
3359 }
3360
3361 S = static_cast<StringLiteral *>(I->getSubExprAsWritten());
3362 } else if (arg->getStmtClass() == Stmt::StringLiteralClass) {
3363 S = static_cast<StringLiteral *>(callExpr->getArg(0));
3364 } else {
3365 return nullptr;
3366 }
3367 return S;
3368}
3369
3370typedef struct {
3371 CXEvalResultKind EvalType;
3372 union {
3373 int intVal;
3374 double floatVal;
3375 char *stringVal;
3376 } EvalData;
3377} ExprEvalResult;
3378
3379void clang_EvalResult_dispose(CXEvalResult E) {
3380 ExprEvalResult *ER = (ExprEvalResult *)E;
3381 if (ER) {
3382 CXEvalResultKind evalType = ER->EvalType;
3383
3384 if (evalType != CXEval_UnExposed && evalType != CXEval_Float &&
3385 evalType != CXEval_Int && ER->EvalData.stringVal) {
3386 free((void *) ER->EvalData.stringVal);
3387 }
3388 free((void *)ER);
3389 }
3390}
3391
3392CXEvalResultKind clang_EvalResult_getKind(CXEvalResult E) {
3393 if (!E) {
3394 return CXEval_UnExposed;
3395 }
3396 return ((ExprEvalResult *)E)->EvalType;
3397}
3398
3399int clang_EvalResult_getAsInt(CXEvalResult E) {
3400 if (!E) {
3401 return 0;
3402 }
3403 return ((ExprEvalResult *)E)->EvalData.intVal;
3404}
3405
3406double clang_EvalResult_getAsDouble(CXEvalResult E) {
3407 if (!E) {
3408 return 0;
3409 }
3410 return ((ExprEvalResult *)E)->EvalData.floatVal;
3411}
3412
3413const char* clang_EvalResult_getAsStr(CXEvalResult E) {
3414 if (!E) {
3415 return nullptr;
3416 }
3417 return ((ExprEvalResult *)E)->EvalData.stringVal;
3418}
3419
3420static const ExprEvalResult* evaluateExpr(Expr *expr, CXCursor C) {
3421 Expr::EvalResult ER;
3422 ASTContext &ctx = getCursorContext(C);
3423 if (!expr) {
3424 return nullptr;
3425 }
3426 expr = expr->IgnoreParens();
3427 bool res = expr->EvaluateAsRValue(ER, ctx);
3428 QualType rettype;
3429 CallExpr *callExpr;
3430 ExprEvalResult *result = (ExprEvalResult *) malloc(sizeof(ExprEvalResult));
3431 if (!result) {
3432 return nullptr;
3433 }
3434 result->EvalType = CXEval_UnExposed;
3435
3436 if (res) {
3437
3438 if (ER.Val.isInt()) {
3439 result->EvalType = CXEval_Int;
3440 result->EvalData.intVal = ER.Val.getInt().getExtValue();
3441 return result;
3442 } else if (ER.Val.isFloat()) {
3443
3444 llvm::SmallVector<char, 100> Buffer;
3445 ER.Val.getFloat().toString(Buffer);
3446 std::string floatStr(Buffer.data(), Buffer.size());
3447 result->EvalType = CXEval_Float;
3448 bool ignored;
3449 llvm::APFloat apFloat = ER.Val.getFloat();
3450 apFloat.convert(llvm::APFloat::IEEEdouble,
3451 llvm::APFloat::rmNearestTiesToEven, &ignored);
3452 result->EvalData.floatVal = apFloat.convertToDouble();
3453 return result;
3454
3455 } else if (expr->getStmtClass() == Stmt::ImplicitCastExprClass) {
3456
3457 const ImplicitCastExpr *I = dyn_cast<ImplicitCastExpr>(expr);
3458 auto *subExpr = I->getSubExprAsWritten();
3459 if (subExpr->getStmtClass() == Stmt::StringLiteralClass ||
3460 subExpr->getStmtClass() == Stmt::ObjCStringLiteralClass) {
3461
3462 const StringLiteral *StrE = nullptr;
3463 const ObjCStringLiteral *ObjCExpr;
3464 ObjCExpr = dyn_cast<ObjCStringLiteral>(subExpr);
3465
3466 if (ObjCExpr) {
3467 StrE = ObjCExpr->getString();
3468 result->EvalType = CXEval_ObjCStrLiteral;
3469 } else {
3470 StrE = cast<StringLiteral>(I->getSubExprAsWritten());
3471 result->EvalType = CXEval_StrLiteral;
3472 }
3473
3474 std::string strRef(StrE->getString().str());
3475 result->EvalData.stringVal = (char *)malloc(strRef.size()+1);
3476 strncpy((char*)result->EvalData.stringVal, strRef.c_str(),
3477 strRef.size());
3478 result->EvalData.stringVal[strRef.size()] = '\0';
3479 return result;
3480 }
3481
3482 } else if (expr->getStmtClass() == Stmt::ObjCStringLiteralClass ||
3483 expr->getStmtClass() == Stmt::StringLiteralClass) {
3484
3485 const StringLiteral *StrE = nullptr;
3486 const ObjCStringLiteral *ObjCExpr;
3487 ObjCExpr = dyn_cast<ObjCStringLiteral>(expr);
3488
3489 if (ObjCExpr) {
3490 StrE = ObjCExpr->getString();
3491 result->EvalType = CXEval_ObjCStrLiteral;
3492 } else {
3493 StrE = cast<StringLiteral>(expr);
3494 result->EvalType = CXEval_StrLiteral;
3495 }
3496
3497 std::string strRef(StrE->getString().str());
3498 result->EvalData.stringVal = (char *)malloc(strRef.size()+1);
3499 strncpy((char*)result->EvalData.stringVal, strRef.c_str(),
3500 strRef.size());
3501 result->EvalData.stringVal[strRef.size()] = '\0';
3502 return result;
3503
3504 } else if (expr->getStmtClass() == Stmt::CStyleCastExprClass) {
3505
3506 CStyleCastExpr *CC = static_cast<CStyleCastExpr *>(expr);
3507
3508 rettype = CC->getType();
3509 if (rettype.getAsString() == "CFStringRef" &&
3510 CC->getSubExpr()->getStmtClass() == Stmt::CallExprClass) {
3511
3512 callExpr = static_cast<CallExpr *>(CC->getSubExpr());
3513 StringLiteral* S = getCFSTR_value(callExpr);
3514 if (S) {
3515 std::string strLiteral(S->getString().str());
3516 result->EvalType = CXEval_CFStr;
3517
3518 result->EvalData.stringVal = (char *)malloc(strLiteral.size()+1);
3519 strncpy((char*)result->EvalData.stringVal, strLiteral.c_str(),
3520 strLiteral.size());
3521 result->EvalData.stringVal[strLiteral.size()] = '\0';
3522 return result;
3523 }
3524 }
3525
3526 } else if (expr->getStmtClass() == Stmt::CallExprClass) {
3527
3528 callExpr = static_cast<CallExpr *>(expr);
3529 rettype = callExpr->getCallReturnType(ctx);
3530
3531 if (rettype->isVectorType() || callExpr->getNumArgs() > 1) {
3532 return nullptr;
3533 }
3534 if (rettype->isIntegralType(ctx) || rettype->isRealFloatingType()) {
3535 if(callExpr->getNumArgs() == 1 &&
3536 !callExpr->getArg(0)->getType()->isIntegralType(ctx)){
3537
3538 return nullptr;
3539 }
3540 } else if(rettype.getAsString() == "CFStringRef") {
3541
3542 StringLiteral* S = getCFSTR_value(callExpr);
3543 if (S) {
3544 std::string strLiteral(S->getString().str());
3545 result->EvalType = CXEval_CFStr;
3546 result->EvalData.stringVal = (char *)malloc(strLiteral.size()+1);
3547 strncpy((char*)result->EvalData.stringVal, strLiteral.c_str(),
3548 strLiteral.size());
3549 result->EvalData.stringVal[strLiteral.size()] = '\0';
3550 return result;
3551 }
3552 }
3553
3554 } else if (expr->getStmtClass() == Stmt::DeclRefExprClass) {
3555
3556 DeclRefExpr *D = static_cast<DeclRefExpr *>(expr);
3557 ValueDecl *V = D->getDecl();
3558 if (V->getKind() == Decl::Function) {
3559 std::string strName(V->getNameAsString());
3560 result->EvalType = CXEval_Other;
3561 result->EvalData.stringVal = (char *)malloc(strName.size()+1);
3562 strncpy((char*)result->EvalData.stringVal, strName.c_str(),
3563 strName.size());
3564 result->EvalData.stringVal[strName.size()] = '\0';
3565 return result;
3566 }
3567 }
3568
3569 }
3570
3571 clang_EvalResult_dispose((CXEvalResult *)result);
3572 return nullptr;
3573}
3574
3575CXEvalResult clang_Cursor_Evaluate(CXCursor C) {
3576 const Decl *D = getCursorDecl(C);
3577 if (D) {
3578 const Expr *expr = nullptr;
3579 if (auto *Var = dyn_cast<VarDecl>(D)) {
3580 expr = Var->getInit();
3581 } else if (auto *Field = dyn_cast<FieldDecl>(D)) {
3582 expr = Field->getInClassInitializer();
3583 }
3584 if (expr)
3585 return (CXEvalResult)evaluateExpr((Expr *)expr, C);
3586 return nullptr;
3587 }
3588
3589 const CompoundStmt *compoundStmt = dyn_cast_or_null<CompoundStmt>(getCursorStmt(C));
3590 if (compoundStmt) {
3591 Expr *expr = nullptr;
3592 for (auto *bodyIterator : compoundStmt->body()) {
3593 if ((expr = dyn_cast<Expr>(bodyIterator))) {
3594 break;
3595 }
3596 }
3597 if (expr)
3598 return (CXEvalResult)evaluateExpr(expr, C);
3599 }
3600 return nullptr;
3601}
3602
3603unsigned clang_Cursor_hasAttrs(CXCursor C) {
3604 const Decl *D = getCursorDecl(C);
3605 if (!D) {
3606 return 0;
3607 }
3608
3609 if (D->hasAttrs()) {
3610 return 1;
3611 }
3612
3613 return 0;
3614}
Guy Benyei11169dd2012-12-18 14:30:41 +00003615unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
3616 return CXSaveTranslationUnit_None;
3617}
3618
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003619static CXSaveError clang_saveTranslationUnit_Impl(CXTranslationUnit TU,
3620 const char *FileName,
3621 unsigned options) {
3622 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003623 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3624 setThreadBackgroundPriority();
3625
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003626 bool hadError = cxtu::getASTUnit(TU)->Save(FileName);
3627 return hadError ? CXSaveError_Unknown : CXSaveError_None;
Guy Benyei11169dd2012-12-18 14:30:41 +00003628}
3629
3630int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3631 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003632 LOG_FUNC_SECTION {
3633 *Log << TU << ' ' << FileName;
3634 }
3635
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003636 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003637 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003638 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003639 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003640
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003641 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003642 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3643 if (!CXXUnit->hasSema())
3644 return CXSaveError_InvalidTU;
3645
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003646 CXSaveError result;
3647 auto SaveTranslationUnitImpl = [=, &result]() {
3648 result = clang_saveTranslationUnit_Impl(TU, FileName, options);
3649 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003650
3651 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3652 getenv("LIBCLANG_NOTHREADS")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003653 SaveTranslationUnitImpl();
Guy Benyei11169dd2012-12-18 14:30:41 +00003654
3655 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3656 PrintLibclangResourceUsage(TU);
3657
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003658 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003659 }
3660
3661 // We have an AST that has invalid nodes due to compiler errors.
3662 // Use a crash recovery thread for protection.
3663
3664 llvm::CrashRecoveryContext CRC;
3665
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003666 if (!RunSafely(CRC, SaveTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003667 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3668 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3669 fprintf(stderr, " 'options' : %d,\n", options);
3670 fprintf(stderr, "}\n");
3671
3672 return CXSaveError_Unknown;
3673
3674 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3675 PrintLibclangResourceUsage(TU);
3676 }
3677
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003678 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003679}
3680
3681void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3682 if (CTUnit) {
3683 // If the translation unit has been marked as unsafe to free, just discard
3684 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003685 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3686 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003687 return;
3688
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003689 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003690 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003691 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3692 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003693 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003694 delete CTUnit;
3695 }
3696}
3697
3698unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3699 return CXReparse_None;
3700}
3701
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003702static CXErrorCode
3703clang_reparseTranslationUnit_Impl(CXTranslationUnit TU,
3704 ArrayRef<CXUnsavedFile> unsaved_files,
3705 unsigned options) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003706 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003707 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003708 LOG_BAD_TU(TU);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003709 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003710 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003711
3712 // Reset the associated diagnostics.
3713 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003714 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003715
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003716 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003717 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3718 setThreadBackgroundPriority();
3719
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003720 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003721 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003722
3723 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3724 new std::vector<ASTUnit::RemappedFile>());
3725
Guy Benyei11169dd2012-12-18 14:30:41 +00003726 // Recover resources if we crash before exiting this function.
3727 llvm::CrashRecoveryContextCleanupRegistrar<
3728 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003729
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003730 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003731 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003732 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003733 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003734 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003735
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003736 if (!CXXUnit->Reparse(CXXIdx->getPCHContainerOperations(),
3737 *RemappedFiles.get()))
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003738 return CXError_Success;
3739 if (isASTReadError(CXXUnit))
3740 return CXError_ASTReadError;
3741 return CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003742}
3743
3744int clang_reparseTranslationUnit(CXTranslationUnit TU,
3745 unsigned num_unsaved_files,
3746 struct CXUnsavedFile *unsaved_files,
3747 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003748 LOG_FUNC_SECTION {
3749 *Log << TU;
3750 }
3751
Alp Toker9d85b182014-07-07 01:23:14 +00003752 if (num_unsaved_files && !unsaved_files)
3753 return CXError_InvalidArguments;
3754
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003755 CXErrorCode result;
3756 auto ReparseTranslationUnitImpl = [=, &result]() {
3757 result = clang_reparseTranslationUnit_Impl(
3758 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options);
3759 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003760
3761 if (getenv("LIBCLANG_NOTHREADS")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003762 ReparseTranslationUnitImpl();
Alp Toker5c532982014-07-07 22:42:03 +00003763 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003764 }
3765
3766 llvm::CrashRecoveryContext CRC;
3767
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003768 if (!RunSafely(CRC, ReparseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003769 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003770 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003771 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003772 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3773 PrintLibclangResourceUsage(TU);
3774
Alp Toker5c532982014-07-07 22:42:03 +00003775 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003776}
3777
3778
3779CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003780 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003781 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003782 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003783 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003784
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003785 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003786 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003787}
3788
3789CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003790 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003791 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003792 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003793 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003794
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003795 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003796 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3797}
3798
3799} // end: extern "C"
3800
3801//===----------------------------------------------------------------------===//
3802// CXFile Operations.
3803//===----------------------------------------------------------------------===//
3804
3805extern "C" {
3806CXString clang_getFileName(CXFile SFile) {
3807 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003808 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003809
3810 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003811 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003812}
3813
3814time_t clang_getFileTime(CXFile SFile) {
3815 if (!SFile)
3816 return 0;
3817
3818 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3819 return FEnt->getModificationTime();
3820}
3821
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003822CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003823 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003824 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003825 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003826 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003827
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003828 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003829
3830 FileManager &FMgr = CXXUnit->getFileManager();
3831 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3832}
3833
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003834unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3835 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003836 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003837 LOG_BAD_TU(TU);
3838 return 0;
3839 }
3840
3841 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003842 return 0;
3843
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003844 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003845 FileEntry *FEnt = static_cast<FileEntry *>(file);
3846 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3847 .isFileMultipleIncludeGuarded(FEnt);
3848}
3849
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003850int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3851 if (!file || !outID)
3852 return 1;
3853
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003854 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003855 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3856 outID->data[0] = ID.getDevice();
3857 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003858 outID->data[2] = FEnt->getModificationTime();
3859 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003860}
3861
Argyrios Kyrtzidisac3997e2014-08-16 00:26:19 +00003862int clang_File_isEqual(CXFile file1, CXFile file2) {
3863 if (file1 == file2)
3864 return true;
3865
3866 if (!file1 || !file2)
3867 return false;
3868
3869 FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
3870 FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
3871 return FEnt1->getUniqueID() == FEnt2->getUniqueID();
3872}
3873
Guy Benyei11169dd2012-12-18 14:30:41 +00003874} // end: extern "C"
3875
3876//===----------------------------------------------------------------------===//
3877// CXCursor Operations.
3878//===----------------------------------------------------------------------===//
3879
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003880static const Decl *getDeclFromExpr(const Stmt *E) {
3881 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003882 return getDeclFromExpr(CE->getSubExpr());
3883
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003884 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003885 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003886 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003887 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003888 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003889 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003890 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003891 if (PRE->isExplicitProperty())
3892 return PRE->getExplicitProperty();
3893 // It could be messaging both getter and setter as in:
3894 // ++myobj.myprop;
3895 // in which case prefer to associate the setter since it is less obvious
3896 // from inspecting the source that the setter is going to get called.
3897 if (PRE->isMessagingSetter())
3898 return PRE->getImplicitPropertySetter();
3899 return PRE->getImplicitPropertyGetter();
3900 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003901 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003902 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003903 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003904 if (Expr *Src = OVE->getSourceExpr())
3905 return getDeclFromExpr(Src);
3906
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003907 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003908 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003909 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003910 if (!CE->isElidable())
3911 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003912 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003913 return OME->getMethodDecl();
3914
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003915 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003916 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003917 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003918 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3919 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003920 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003921 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3922 isa<ParmVarDecl>(SizeOfPack->getPack()))
3923 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003924
3925 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003926}
3927
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003928static SourceLocation getLocationFromExpr(const Expr *E) {
3929 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003930 return getLocationFromExpr(CE->getSubExpr());
3931
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003932 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003933 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003934 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003935 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003936 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003937 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003938 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003939 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003940 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003941 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003942 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003943 return PropRef->getLocation();
3944
3945 return E->getLocStart();
3946}
3947
Aaron Ballmana85d3f82015-11-12 15:25:06 +00003948static std::string getMangledStructor(std::unique_ptr<MangleContext> &M,
3949 std::unique_ptr<llvm::DataLayout> &DL,
3950 const NamedDecl *ND,
3951 unsigned StructorType) {
3952 std::string FrontendBuf;
3953 llvm::raw_string_ostream FOS(FrontendBuf);
3954
3955 if (const auto *CD = dyn_cast_or_null<CXXConstructorDecl>(ND))
3956 M->mangleCXXCtor(CD, static_cast<CXXCtorType>(StructorType), FOS);
3957 else if (const auto *DD = dyn_cast_or_null<CXXDestructorDecl>(ND))
3958 M->mangleCXXDtor(DD, static_cast<CXXDtorType>(StructorType), FOS);
3959
3960 std::string BackendBuf;
3961 llvm::raw_string_ostream BOS(BackendBuf);
3962
3963 llvm::Mangler::getNameWithPrefix(BOS, llvm::Twine(FOS.str()), *DL);
3964
3965 return BOS.str();
3966}
3967
Guy Benyei11169dd2012-12-18 14:30:41 +00003968extern "C" {
3969
3970unsigned clang_visitChildren(CXCursor parent,
3971 CXCursorVisitor visitor,
3972 CXClientData client_data) {
3973 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3974 /*VisitPreprocessorLast=*/false);
3975 return CursorVis.VisitChildren(parent);
3976}
3977
3978#ifndef __has_feature
3979#define __has_feature(x) 0
3980#endif
3981#if __has_feature(blocks)
3982typedef enum CXChildVisitResult
3983 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3984
3985static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3986 CXClientData client_data) {
3987 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3988 return block(cursor, parent);
3989}
3990#else
3991// If we are compiled with a compiler that doesn't have native blocks support,
3992// define and call the block manually, so the
3993typedef struct _CXChildVisitResult
3994{
3995 void *isa;
3996 int flags;
3997 int reserved;
3998 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3999 CXCursor);
4000} *CXCursorVisitorBlock;
4001
4002static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
4003 CXClientData client_data) {
4004 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
4005 return block->invoke(block, cursor, parent);
4006}
4007#endif
4008
4009
4010unsigned clang_visitChildrenWithBlock(CXCursor parent,
4011 CXCursorVisitorBlock block) {
4012 return clang_visitChildren(parent, visitWithBlock, block);
4013}
4014
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004015static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004016 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004017 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004018
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004019 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004020 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004021 if (const ObjCPropertyImplDecl *PropImpl =
4022 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004023 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004024 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004025
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004026 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004027 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004028 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004029
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004030 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004031 }
4032
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004033 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004034 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004035
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004036 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00004037 // No, this isn't the same as the code below. getIdentifier() is non-virtual
4038 // and returns different names. NamedDecl returns the class name and
4039 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004040 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004041
4042 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004043 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004044
4045 SmallString<1024> S;
4046 llvm::raw_svector_ostream os(S);
4047 ND->printName(os);
4048
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004049 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004050}
4051
4052CXString clang_getCursorSpelling(CXCursor C) {
4053 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00004054 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004055
4056 if (clang_isReference(C.kind)) {
4057 switch (C.kind) {
4058 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004059 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004060 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004061 }
4062 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004063 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004064 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004065 }
4066 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004067 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004068 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004069 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004070 }
4071 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004072 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004073 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004074 }
4075 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004076 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004077 assert(Type && "Missing type decl");
4078
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004079 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00004080 getAsString());
4081 }
4082 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004083 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004084 assert(Template && "Missing template decl");
4085
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004086 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004087 }
4088
4089 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004090 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004091 assert(NS && "Missing namespace decl");
4092
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004093 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004094 }
4095
4096 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004097 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004098 assert(Field && "Missing member decl");
4099
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004100 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004101 }
4102
4103 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004104 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004105 assert(Label && "Missing label");
4106
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004107 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004108 }
4109
4110 case CXCursor_OverloadedDeclRef: {
4111 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004112 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
4113 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004114 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004115 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004116 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004117 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004118 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004119 OverloadedTemplateStorage *Ovl
4120 = Storage.get<OverloadedTemplateStorage*>();
4121 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004122 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004123 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004124 }
4125
4126 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004127 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004128 assert(Var && "Missing variable decl");
4129
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004130 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004131 }
4132
4133 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004134 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00004135 }
4136 }
4137
4138 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00004139 const Expr *E = getCursorExpr(C);
4140
4141 if (C.kind == CXCursor_ObjCStringLiteral ||
4142 C.kind == CXCursor_StringLiteral) {
4143 const StringLiteral *SLit;
4144 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
4145 SLit = OSL->getString();
4146 } else {
4147 SLit = cast<StringLiteral>(E);
4148 }
4149 SmallString<256> Buf;
4150 llvm::raw_svector_ostream OS(Buf);
4151 SLit->outputString(OS);
4152 return cxstring::createDup(OS.str());
4153 }
4154
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004155 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004156 if (D)
4157 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004158 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004159 }
4160
4161 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004162 const Stmt *S = getCursorStmt(C);
4163 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004164 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004165
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004166 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004167 }
4168
4169 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004170 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00004171 ->getNameStart());
4172
4173 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004174 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00004175 ->getNameStart());
4176
4177 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004178 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004179
4180 if (clang_isDeclaration(C.kind))
4181 return getDeclSpelling(getCursorDecl(C));
4182
4183 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00004184 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004185 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00004186 }
4187
4188 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00004189 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004190 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00004191 }
4192
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004193 if (C.kind == CXCursor_PackedAttr) {
4194 return cxstring::createRef("packed");
4195 }
4196
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00004197 if (C.kind == CXCursor_VisibilityAttr) {
4198 const VisibilityAttr *AA = cast<VisibilityAttr>(cxcursor::getCursorAttr(C));
4199 switch (AA->getVisibility()) {
4200 case VisibilityAttr::VisibilityType::Default:
4201 return cxstring::createRef("default");
4202 case VisibilityAttr::VisibilityType::Hidden:
4203 return cxstring::createRef("hidden");
4204 case VisibilityAttr::VisibilityType::Protected:
4205 return cxstring::createRef("protected");
4206 }
4207 llvm_unreachable("unknown visibility type");
4208 }
4209
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004210 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004211}
4212
4213CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
4214 unsigned pieceIndex,
4215 unsigned options) {
4216 if (clang_Cursor_isNull(C))
4217 return clang_getNullRange();
4218
4219 ASTContext &Ctx = getCursorContext(C);
4220
4221 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004222 const Stmt *S = getCursorStmt(C);
4223 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004224 if (pieceIndex > 0)
4225 return clang_getNullRange();
4226 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
4227 }
4228
4229 return clang_getNullRange();
4230 }
4231
4232 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004233 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00004234 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
4235 if (pieceIndex >= ME->getNumSelectorLocs())
4236 return clang_getNullRange();
4237 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
4238 }
4239 }
4240
4241 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
4242 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004243 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00004244 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
4245 if (pieceIndex >= MD->getNumSelectorLocs())
4246 return clang_getNullRange();
4247 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
4248 }
4249 }
4250
4251 if (C.kind == CXCursor_ObjCCategoryDecl ||
4252 C.kind == CXCursor_ObjCCategoryImplDecl) {
4253 if (pieceIndex > 0)
4254 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004255 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00004256 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
4257 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004258 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00004259 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
4260 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
4261 }
4262
4263 if (C.kind == CXCursor_ModuleImportDecl) {
4264 if (pieceIndex > 0)
4265 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004266 if (const ImportDecl *ImportD =
4267 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004268 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
4269 if (!Locs.empty())
4270 return cxloc::translateSourceRange(Ctx,
4271 SourceRange(Locs.front(), Locs.back()));
4272 }
4273 return clang_getNullRange();
4274 }
4275
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00004276 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
4277 C.kind == CXCursor_ConversionFunction) {
4278 if (pieceIndex > 0)
4279 return clang_getNullRange();
4280 if (const FunctionDecl *FD =
4281 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
4282 DeclarationNameInfo FunctionName = FD->getNameInfo();
4283 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
4284 }
4285 return clang_getNullRange();
4286 }
4287
Guy Benyei11169dd2012-12-18 14:30:41 +00004288 // FIXME: A CXCursor_InclusionDirective should give the location of the
4289 // filename, but we don't keep track of this.
4290
4291 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
4292 // but we don't keep track of this.
4293
4294 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
4295 // but we don't keep track of this.
4296
4297 // Default handling, give the location of the cursor.
4298
4299 if (pieceIndex > 0)
4300 return clang_getNullRange();
4301
4302 CXSourceLocation CXLoc = clang_getCursorLocation(C);
4303 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
4304 return cxloc::translateSourceRange(Ctx, Loc);
4305}
4306
Eli Bendersky44a206f2014-07-31 18:04:56 +00004307CXString clang_Cursor_getMangling(CXCursor C) {
4308 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
4309 return cxstring::createEmpty();
4310
Eli Bendersky44a206f2014-07-31 18:04:56 +00004311 // Mangling only works for functions and variables.
Eli Bendersky79759592014-08-01 15:01:10 +00004312 const Decl *D = getCursorDecl(C);
Eli Bendersky44a206f2014-07-31 18:04:56 +00004313 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
4314 return cxstring::createEmpty();
4315
Eli Bendersky79759592014-08-01 15:01:10 +00004316 // First apply frontend mangling.
Eli Bendersky44a206f2014-07-31 18:04:56 +00004317 const NamedDecl *ND = cast<NamedDecl>(D);
Eli Bendersky79759592014-08-01 15:01:10 +00004318 ASTContext &Ctx = ND->getASTContext();
4319 std::unique_ptr<MangleContext> MC(Ctx.createMangleContext());
Eli Bendersky44a206f2014-07-31 18:04:56 +00004320
Eli Bendersky79759592014-08-01 15:01:10 +00004321 std::string FrontendBuf;
4322 llvm::raw_string_ostream FrontendBufOS(FrontendBuf);
Ehsan Akhgarif8d44de2015-10-08 00:01:20 +00004323 if (MC->shouldMangleDeclName(ND)) {
4324 MC->mangleName(ND, FrontendBufOS);
4325 } else {
4326 ND->printName(FrontendBufOS);
4327 }
Eli Bendersky44a206f2014-07-31 18:04:56 +00004328
Eli Bendersky79759592014-08-01 15:01:10 +00004329 // Now apply backend mangling.
4330 std::unique_ptr<llvm::DataLayout> DL(
Eric Christopher964a5f32015-08-05 23:48:05 +00004331 new llvm::DataLayout(Ctx.getTargetInfo().getDataLayoutString()));
Eli Bendersky79759592014-08-01 15:01:10 +00004332
4333 std::string FinalBuf;
4334 llvm::raw_string_ostream FinalBufOS(FinalBuf);
Rafael Espindolab633d202015-06-23 13:59:36 +00004335 llvm::Mangler::getNameWithPrefix(FinalBufOS, llvm::Twine(FrontendBufOS.str()),
4336 *DL);
Eli Bendersky79759592014-08-01 15:01:10 +00004337
4338 return cxstring::createDup(FinalBufOS.str());
Eli Bendersky44a206f2014-07-31 18:04:56 +00004339}
4340
Saleem Abdulrasool60034432015-11-12 03:57:22 +00004341CXStringSet *clang_Cursor_getCXXManglings(CXCursor C) {
4342 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
4343 return nullptr;
4344
4345 const Decl *D = getCursorDecl(C);
4346 if (!(isa<CXXRecordDecl>(D) || isa<CXXMethodDecl>(D)))
4347 return nullptr;
4348
4349 const NamedDecl *ND = cast<NamedDecl>(D);
4350
4351 ASTContext &Ctx = ND->getASTContext();
4352 std::unique_ptr<MangleContext> M(Ctx.createMangleContext());
4353 std::unique_ptr<llvm::DataLayout> DL(
4354 new llvm::DataLayout(Ctx.getTargetInfo().getDataLayoutString()));
4355
4356 std::vector<std::string> Manglings;
4357
4358 auto hasDefaultCXXMethodCC = [](ASTContext &C, const CXXMethodDecl *MD) {
4359 auto DefaultCC = C.getDefaultCallingConvention(/*IsVariadic=*/false,
4360 /*IsCSSMethod=*/true);
4361 auto CC = MD->getType()->getAs<FunctionProtoType>()->getCallConv();
4362 return CC == DefaultCC;
4363 };
4364
4365 if (const auto *CD = dyn_cast_or_null<CXXConstructorDecl>(ND)) {
4366 Manglings.emplace_back(getMangledStructor(M, DL, CD, Ctor_Base));
4367
4368 if (Ctx.getTargetInfo().getCXXABI().isItaniumFamily())
4369 if (!CD->getParent()->isAbstract())
4370 Manglings.emplace_back(getMangledStructor(M, DL, CD, Ctor_Complete));
4371
4372 if (Ctx.getTargetInfo().getCXXABI().isMicrosoft())
4373 if (CD->hasAttr<DLLExportAttr>() && CD->isDefaultConstructor())
4374 if (!(hasDefaultCXXMethodCC(Ctx, CD) && CD->getNumParams() == 0))
4375 Manglings.emplace_back(getMangledStructor(M, DL, CD,
4376 Ctor_DefaultClosure));
4377 } else if (const auto *DD = dyn_cast_or_null<CXXDestructorDecl>(ND)) {
4378 Manglings.emplace_back(getMangledStructor(M, DL, DD, Dtor_Base));
4379 if (Ctx.getTargetInfo().getCXXABI().isItaniumFamily()) {
4380 Manglings.emplace_back(getMangledStructor(M, DL, DD, Dtor_Complete));
Saleem Abdulrasoold5af8ae2015-12-10 06:30:23 +00004381 if (DD->isVirtual())
Saleem Abdulrasool60034432015-11-12 03:57:22 +00004382 Manglings.emplace_back(getMangledStructor(M, DL, DD, Dtor_Deleting));
4383 }
4384 }
4385
4386 return cxstring::createSet(Manglings);
4387}
4388
Guy Benyei11169dd2012-12-18 14:30:41 +00004389CXString clang_getCursorDisplayName(CXCursor C) {
4390 if (!clang_isDeclaration(C.kind))
4391 return clang_getCursorSpelling(C);
4392
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004393 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004394 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004395 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004396
4397 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004398 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004399 D = FunTmpl->getTemplatedDecl();
4400
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004401 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004402 SmallString<64> Str;
4403 llvm::raw_svector_ostream OS(Str);
4404 OS << *Function;
4405 if (Function->getPrimaryTemplate())
4406 OS << "<>";
4407 OS << "(";
4408 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
4409 if (I)
4410 OS << ", ";
4411 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
4412 }
4413
4414 if (Function->isVariadic()) {
4415 if (Function->getNumParams())
4416 OS << ", ";
4417 OS << "...";
4418 }
4419 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004420 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004421 }
4422
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004423 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004424 SmallString<64> Str;
4425 llvm::raw_svector_ostream OS(Str);
4426 OS << *ClassTemplate;
4427 OS << "<";
4428 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
4429 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
4430 if (I)
4431 OS << ", ";
4432
4433 NamedDecl *Param = Params->getParam(I);
4434 if (Param->getIdentifier()) {
4435 OS << Param->getIdentifier()->getName();
4436 continue;
4437 }
4438
4439 // There is no parameter name, which makes this tricky. Try to come up
4440 // with something useful that isn't too long.
4441 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
4442 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
4443 else if (NonTypeTemplateParmDecl *NTTP
4444 = dyn_cast<NonTypeTemplateParmDecl>(Param))
4445 OS << NTTP->getType().getAsString(Policy);
4446 else
4447 OS << "template<...> class";
4448 }
4449
4450 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004451 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004452 }
4453
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004454 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00004455 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
4456 // If the type was explicitly written, use that.
4457 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004458 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00004459
Benjamin Kramer9170e912013-02-22 15:46:01 +00004460 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00004461 llvm::raw_svector_ostream OS(Str);
4462 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00004463 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00004464 ClassSpec->getTemplateArgs().data(),
4465 ClassSpec->getTemplateArgs().size(),
4466 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004467 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004468 }
4469
4470 return clang_getCursorSpelling(C);
4471}
4472
4473CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
4474 switch (Kind) {
4475 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004476 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004477 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004478 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004479 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004480 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004481 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004482 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004483 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004484 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004485 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004486 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004487 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004488 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004489 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004490 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004491 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004492 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004493 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004494 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004495 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004496 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004497 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004498 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004499 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004500 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004501 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004502 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004503 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004504 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004505 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004506 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004507 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004508 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004509 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004510 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004511 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004512 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004513 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004514 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00004515 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004516 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004517 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004518 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004519 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004520 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004521 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004522 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004523 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004524 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004525 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004526 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004527 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004528 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004529 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004530 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004531 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004532 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004533 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004534 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004535 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004536 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004537 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004538 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004539 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004540 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004541 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004542 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004543 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004544 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004545 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004546 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004547 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004548 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004549 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004550 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004551 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004552 return cxstring::createRef("ArraySubscriptExpr");
Alexey Bataev1a3320e2015-08-25 14:24:04 +00004553 case CXCursor_OMPArraySectionExpr:
4554 return cxstring::createRef("OMPArraySectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004555 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004556 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004557 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004558 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004559 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004560 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004561 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004562 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004563 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004564 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004565 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004566 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004567 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004568 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004569 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004570 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004571 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004572 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004573 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004574 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004575 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004576 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004577 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004578 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004579 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004580 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004581 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004582 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004583 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004584 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004585 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004586 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004587 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004588 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004589 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004590 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004591 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004592 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004593 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004594 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004595 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004596 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004597 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004598 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004599 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004600 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004601 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004602 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004603 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004604 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00004605 case CXCursor_ObjCSelfExpr:
4606 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004607 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004608 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004609 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004610 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004611 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004612 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004613 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004614 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004615 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004616 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004617 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004618 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004619 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004620 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004621 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004622 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004623 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004624 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004625 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004626 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004627 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004628 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004629 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004630 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004631 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004632 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004633 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004634 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004635 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004636 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004637 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004638 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004639 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004640 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004641 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004642 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004643 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004644 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004645 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004646 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004647 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004648 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004649 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004650 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004651 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004652 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004653 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004654 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004655 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004656 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004657 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004658 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004659 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004660 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004661 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004662 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004663 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004664 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004665 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004666 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004667 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004668 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004669 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004670 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004671 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004672 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004673 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004674 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004675 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004676 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004677 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004678 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004679 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004680 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004681 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004682 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004683 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004684 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004685 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004686 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004687 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004688 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004689 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004690 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004691 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004692 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004693 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004694 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00004695 case CXCursor_SEHLeaveStmt:
4696 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004697 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004698 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004699 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004700 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00004701 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004702 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00004703 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004704 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00004705 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004706 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00004707 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004708 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00004709 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004710 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004711 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004712 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004713 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004714 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004715 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004716 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004717 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004718 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004719 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004720 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004721 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004722 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004723 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004724 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004725 case CXCursor_PackedAttr:
4726 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00004727 case CXCursor_PureAttr:
4728 return cxstring::createRef("attribute(pure)");
4729 case CXCursor_ConstAttr:
4730 return cxstring::createRef("attribute(const)");
4731 case CXCursor_NoDuplicateAttr:
4732 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00004733 case CXCursor_CUDAConstantAttr:
4734 return cxstring::createRef("attribute(constant)");
4735 case CXCursor_CUDADeviceAttr:
4736 return cxstring::createRef("attribute(device)");
4737 case CXCursor_CUDAGlobalAttr:
4738 return cxstring::createRef("attribute(global)");
4739 case CXCursor_CUDAHostAttr:
4740 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00004741 case CXCursor_CUDASharedAttr:
4742 return cxstring::createRef("attribute(shared)");
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00004743 case CXCursor_VisibilityAttr:
4744 return cxstring::createRef("attribute(visibility)");
Saleem Abdulrasool8aa0b802015-12-10 18:45:18 +00004745 case CXCursor_DLLExport:
4746 return cxstring::createRef("attribute(dllexport)");
4747 case CXCursor_DLLImport:
4748 return cxstring::createRef("attribute(dllimport)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004749 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004750 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004751 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004752 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00004753 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004754 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004755 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004756 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004757 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004758 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00004759 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004760 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00004761 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004762 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004763 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004764 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004765 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004766 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004767 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004768 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004769 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004770 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004771 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004772 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004773 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004774 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004775 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004776 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004777 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004778 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004779 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004780 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004781 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004782 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004783 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004784 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004785 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004786 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004787 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004788 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004789 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004790 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004791 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004792 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004793 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004794 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004795 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004796 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004797 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004798 return cxstring::createRef("OMPParallelDirective");
4799 case CXCursor_OMPSimdDirective:
4800 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004801 case CXCursor_OMPForDirective:
4802 return cxstring::createRef("OMPForDirective");
Alexander Musmanf82886e2014-09-18 05:12:34 +00004803 case CXCursor_OMPForSimdDirective:
4804 return cxstring::createRef("OMPForSimdDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004805 case CXCursor_OMPSectionsDirective:
4806 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004807 case CXCursor_OMPSectionDirective:
4808 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004809 case CXCursor_OMPSingleDirective:
4810 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004811 case CXCursor_OMPMasterDirective:
4812 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004813 case CXCursor_OMPCriticalDirective:
4814 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004815 case CXCursor_OMPParallelForDirective:
4816 return cxstring::createRef("OMPParallelForDirective");
Alexander Musmane4e893b2014-09-23 09:33:00 +00004817 case CXCursor_OMPParallelForSimdDirective:
4818 return cxstring::createRef("OMPParallelForSimdDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004819 case CXCursor_OMPParallelSectionsDirective:
4820 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004821 case CXCursor_OMPTaskDirective:
4822 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004823 case CXCursor_OMPTaskyieldDirective:
4824 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004825 case CXCursor_OMPBarrierDirective:
4826 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004827 case CXCursor_OMPTaskwaitDirective:
4828 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00004829 case CXCursor_OMPTaskgroupDirective:
4830 return cxstring::createRef("OMPTaskgroupDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00004831 case CXCursor_OMPFlushDirective:
4832 return cxstring::createRef("OMPFlushDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004833 case CXCursor_OMPOrderedDirective:
4834 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00004835 case CXCursor_OMPAtomicDirective:
4836 return cxstring::createRef("OMPAtomicDirective");
Alexey Bataev0bd520b2014-09-19 08:19:49 +00004837 case CXCursor_OMPTargetDirective:
4838 return cxstring::createRef("OMPTargetDirective");
Michael Wong65f367f2015-07-21 13:44:28 +00004839 case CXCursor_OMPTargetDataDirective:
4840 return cxstring::createRef("OMPTargetDataDirective");
Alexey Bataev13314bf2014-10-09 04:18:56 +00004841 case CXCursor_OMPTeamsDirective:
4842 return cxstring::createRef("OMPTeamsDirective");
Alexey Bataev6d4ed052015-07-01 06:57:41 +00004843 case CXCursor_OMPCancellationPointDirective:
4844 return cxstring::createRef("OMPCancellationPointDirective");
Alexey Bataev80909872015-07-02 11:25:17 +00004845 case CXCursor_OMPCancelDirective:
4846 return cxstring::createRef("OMPCancelDirective");
Alexey Bataev49f6e782015-12-01 04:18:41 +00004847 case CXCursor_OMPTaskLoopDirective:
4848 return cxstring::createRef("OMPTaskLoopDirective");
Alexey Bataev0a6ed842015-12-03 09:40:15 +00004849 case CXCursor_OMPTaskLoopSimdDirective:
4850 return cxstring::createRef("OMPTaskLoopSimdDirective");
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00004851 case CXCursor_OMPDistributeDirective:
4852 return cxstring::createRef("OMPDistributeDirective");
Francisco Lopes da Silva975a9f62015-01-21 16:24:11 +00004853 case CXCursor_OverloadCandidate:
4854 return cxstring::createRef("OverloadCandidate");
Sergey Kalinichev8f3b1872015-11-15 13:48:32 +00004855 case CXCursor_TypeAliasTemplateDecl:
4856 return cxstring::createRef("TypeAliasTemplateDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004857 }
4858
4859 llvm_unreachable("Unhandled CXCursorKind");
4860}
4861
4862struct GetCursorData {
4863 SourceLocation TokenBeginLoc;
4864 bool PointsAtMacroArgExpansion;
4865 bool VisitedObjCPropertyImplDecl;
4866 SourceLocation VisitedDeclaratorDeclStartLoc;
4867 CXCursor &BestCursor;
4868
4869 GetCursorData(SourceManager &SM,
4870 SourceLocation tokenBegin, CXCursor &outputCursor)
4871 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4872 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4873 VisitedObjCPropertyImplDecl = false;
4874 }
4875};
4876
4877static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4878 CXCursor parent,
4879 CXClientData client_data) {
4880 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4881 CXCursor *BestCursor = &Data->BestCursor;
4882
4883 // If we point inside a macro argument we should provide info of what the
4884 // token is so use the actual cursor, don't replace it with a macro expansion
4885 // cursor.
4886 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4887 return CXChildVisit_Recurse;
4888
4889 if (clang_isDeclaration(cursor.kind)) {
4890 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004891 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004892 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4893 if (MD->isImplicit())
4894 return CXChildVisit_Break;
4895
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004896 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004897 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4898 // Check that when we have multiple @class references in the same line,
4899 // that later ones do not override the previous ones.
4900 // If we have:
4901 // @class Foo, Bar;
4902 // source ranges for both start at '@', so 'Bar' will end up overriding
4903 // 'Foo' even though the cursor location was at 'Foo'.
4904 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4905 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004906 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004907 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4908 if (PrevID != ID &&
4909 !PrevID->isThisDeclarationADefinition() &&
4910 !ID->isThisDeclarationADefinition())
4911 return CXChildVisit_Break;
4912 }
4913
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004914 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004915 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4916 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4917 // Check that when we have multiple declarators in the same line,
4918 // that later ones do not override the previous ones.
4919 // If we have:
4920 // int Foo, Bar;
4921 // source ranges for both start at 'int', so 'Bar' will end up overriding
4922 // 'Foo' even though the cursor location was at 'Foo'.
4923 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4924 return CXChildVisit_Break;
4925 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4926
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004927 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004928 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4929 (void)PropImp;
4930 // Check that when we have multiple @synthesize in the same line,
4931 // that later ones do not override the previous ones.
4932 // If we have:
4933 // @synthesize Foo, Bar;
4934 // source ranges for both start at '@', so 'Bar' will end up overriding
4935 // 'Foo' even though the cursor location was at 'Foo'.
4936 if (Data->VisitedObjCPropertyImplDecl)
4937 return CXChildVisit_Break;
4938 Data->VisitedObjCPropertyImplDecl = true;
4939 }
4940 }
4941
4942 if (clang_isExpression(cursor.kind) &&
4943 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004944 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004945 // Avoid having the cursor of an expression replace the declaration cursor
4946 // when the expression source range overlaps the declaration range.
4947 // This can happen for C++ constructor expressions whose range generally
4948 // include the variable declaration, e.g.:
4949 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4950 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4951 D->getLocation() == Data->TokenBeginLoc)
4952 return CXChildVisit_Break;
4953 }
4954 }
4955
4956 // If our current best cursor is the construction of a temporary object,
4957 // don't replace that cursor with a type reference, because we want
4958 // clang_getCursor() to point at the constructor.
4959 if (clang_isExpression(BestCursor->kind) &&
4960 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4961 cursor.kind == CXCursor_TypeRef) {
4962 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4963 // as having the actual point on the type reference.
4964 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4965 return CXChildVisit_Recurse;
4966 }
Douglas Gregore9d95f12015-07-07 03:57:35 +00004967
4968 // If we already have an Objective-C superclass reference, don't
4969 // update it further.
4970 if (BestCursor->kind == CXCursor_ObjCSuperClassRef)
4971 return CXChildVisit_Break;
4972
Guy Benyei11169dd2012-12-18 14:30:41 +00004973 *BestCursor = cursor;
4974 return CXChildVisit_Recurse;
4975}
4976
4977CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004978 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004979 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004980 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004981 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004982
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004983 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004984 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4985
4986 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4987 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4988
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004989 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004990 CXFile SearchFile;
4991 unsigned SearchLine, SearchColumn;
4992 CXFile ResultFile;
4993 unsigned ResultLine, ResultColumn;
4994 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4995 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4996 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004997
4998 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4999 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005000 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00005001 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00005002 SearchFileName = clang_getFileName(SearchFile);
5003 ResultFileName = clang_getFileName(ResultFile);
5004 KindSpelling = clang_getCursorKindSpelling(Result.kind);
5005 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005006 *Log << llvm::format("(%s:%d:%d) = %s",
5007 clang_getCString(SearchFileName), SearchLine, SearchColumn,
5008 clang_getCString(KindSpelling))
5009 << llvm::format("(%s:%d:%d):%s%s",
5010 clang_getCString(ResultFileName), ResultLine, ResultColumn,
5011 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00005012 clang_disposeString(SearchFileName);
5013 clang_disposeString(ResultFileName);
5014 clang_disposeString(KindSpelling);
5015 clang_disposeString(USR);
5016
5017 CXCursor Definition = clang_getCursorDefinition(Result);
5018 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
5019 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
5020 CXString DefinitionKindSpelling
5021 = clang_getCursorKindSpelling(Definition.kind);
5022 CXFile DefinitionFile;
5023 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005024 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00005025 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00005026 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005027 *Log << llvm::format(" -> %s(%s:%d:%d)",
5028 clang_getCString(DefinitionKindSpelling),
5029 clang_getCString(DefinitionFileName),
5030 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00005031 clang_disposeString(DefinitionFileName);
5032 clang_disposeString(DefinitionKindSpelling);
5033 }
5034 }
5035
5036 return Result;
5037}
5038
5039CXCursor clang_getNullCursor(void) {
5040 return MakeCXCursorInvalid(CXCursor_InvalidFile);
5041}
5042
5043unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005044 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
5045 // can't set consistently. For example, when visiting a DeclStmt we will set
5046 // it but we don't set it on the result of clang_getCursorDefinition for
5047 // a reference of the same declaration.
5048 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
5049 // when visiting a DeclStmt currently, the AST should be enhanced to be able
5050 // to provide that kind of info.
5051 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00005052 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005053 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00005054 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005055
Guy Benyei11169dd2012-12-18 14:30:41 +00005056 return X == Y;
5057}
5058
5059unsigned clang_hashCursor(CXCursor C) {
5060 unsigned Index = 0;
5061 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
5062 Index = 1;
5063
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005064 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00005065 std::make_pair(C.kind, C.data[Index]));
5066}
5067
5068unsigned clang_isInvalid(enum CXCursorKind K) {
5069 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
5070}
5071
5072unsigned clang_isDeclaration(enum CXCursorKind K) {
5073 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
5074 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
5075}
5076
5077unsigned clang_isReference(enum CXCursorKind K) {
5078 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
5079}
5080
5081unsigned clang_isExpression(enum CXCursorKind K) {
5082 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
5083}
5084
5085unsigned clang_isStatement(enum CXCursorKind K) {
5086 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
5087}
5088
5089unsigned clang_isAttribute(enum CXCursorKind K) {
5090 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
5091}
5092
5093unsigned clang_isTranslationUnit(enum CXCursorKind K) {
5094 return K == CXCursor_TranslationUnit;
5095}
5096
5097unsigned clang_isPreprocessing(enum CXCursorKind K) {
5098 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
5099}
5100
5101unsigned clang_isUnexposed(enum CXCursorKind K) {
5102 switch (K) {
5103 case CXCursor_UnexposedDecl:
5104 case CXCursor_UnexposedExpr:
5105 case CXCursor_UnexposedStmt:
5106 case CXCursor_UnexposedAttr:
5107 return true;
5108 default:
5109 return false;
5110 }
5111}
5112
5113CXCursorKind clang_getCursorKind(CXCursor C) {
5114 return C.kind;
5115}
5116
5117CXSourceLocation clang_getCursorLocation(CXCursor C) {
5118 if (clang_isReference(C.kind)) {
5119 switch (C.kind) {
5120 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005121 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00005122 = getCursorObjCSuperClassRef(C);
5123 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5124 }
5125
5126 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005127 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00005128 = getCursorObjCProtocolRef(C);
5129 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5130 }
5131
5132 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005133 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00005134 = getCursorObjCClassRef(C);
5135 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5136 }
5137
5138 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005139 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005140 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5141 }
5142
5143 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005144 std::pair<const TemplateDecl *, SourceLocation> P =
5145 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005146 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5147 }
5148
5149 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005150 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005151 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5152 }
5153
5154 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005155 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005156 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5157 }
5158
5159 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005160 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005161 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5162 }
5163
5164 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005165 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005166 if (!BaseSpec)
5167 return clang_getNullLocation();
5168
5169 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
5170 return cxloc::translateSourceLocation(getCursorContext(C),
5171 TSInfo->getTypeLoc().getBeginLoc());
5172
5173 return cxloc::translateSourceLocation(getCursorContext(C),
5174 BaseSpec->getLocStart());
5175 }
5176
5177 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005178 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005179 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
5180 }
5181
5182 case CXCursor_OverloadedDeclRef:
5183 return cxloc::translateSourceLocation(getCursorContext(C),
5184 getCursorOverloadedDeclRef(C).second);
5185
5186 default:
5187 // FIXME: Need a way to enumerate all non-reference cases.
5188 llvm_unreachable("Missed a reference kind");
5189 }
5190 }
5191
5192 if (clang_isExpression(C.kind))
5193 return cxloc::translateSourceLocation(getCursorContext(C),
5194 getLocationFromExpr(getCursorExpr(C)));
5195
5196 if (clang_isStatement(C.kind))
5197 return cxloc::translateSourceLocation(getCursorContext(C),
5198 getCursorStmt(C)->getLocStart());
5199
5200 if (C.kind == CXCursor_PreprocessingDirective) {
5201 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
5202 return cxloc::translateSourceLocation(getCursorContext(C), L);
5203 }
5204
5205 if (C.kind == CXCursor_MacroExpansion) {
5206 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005207 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00005208 return cxloc::translateSourceLocation(getCursorContext(C), L);
5209 }
5210
5211 if (C.kind == CXCursor_MacroDefinition) {
5212 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
5213 return cxloc::translateSourceLocation(getCursorContext(C), L);
5214 }
5215
5216 if (C.kind == CXCursor_InclusionDirective) {
5217 SourceLocation L
5218 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
5219 return cxloc::translateSourceLocation(getCursorContext(C), L);
5220 }
5221
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00005222 if (clang_isAttribute(C.kind)) {
5223 SourceLocation L
5224 = cxcursor::getCursorAttr(C)->getLocation();
5225 return cxloc::translateSourceLocation(getCursorContext(C), L);
5226 }
5227
Guy Benyei11169dd2012-12-18 14:30:41 +00005228 if (!clang_isDeclaration(C.kind))
5229 return clang_getNullLocation();
5230
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005231 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005232 if (!D)
5233 return clang_getNullLocation();
5234
5235 SourceLocation Loc = D->getLocation();
5236 // FIXME: Multiple variables declared in a single declaration
5237 // currently lack the information needed to correctly determine their
5238 // ranges when accounting for the type-specifier. We use context
5239 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
5240 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005241 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005242 if (!cxcursor::isFirstInDeclGroup(C))
5243 Loc = VD->getLocation();
5244 }
5245
5246 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005247 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005248 Loc = MD->getSelectorStartLoc();
5249
5250 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
5251}
5252
5253} // end extern "C"
5254
5255CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
5256 assert(TU);
5257
5258 // Guard against an invalid SourceLocation, or we may assert in one
5259 // of the following calls.
5260 if (SLoc.isInvalid())
5261 return clang_getNullCursor();
5262
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005263 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005264
5265 // Translate the given source location to make it point at the beginning of
5266 // the token under the cursor.
5267 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
5268 CXXUnit->getASTContext().getLangOpts());
5269
5270 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
5271 if (SLoc.isValid()) {
5272 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
5273 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
5274 /*VisitPreprocessorLast=*/true,
5275 /*VisitIncludedEntities=*/false,
5276 SourceLocation(SLoc));
5277 CursorVis.visitFileRegion();
5278 }
5279
5280 return Result;
5281}
5282
5283static SourceRange getRawCursorExtent(CXCursor C) {
5284 if (clang_isReference(C.kind)) {
5285 switch (C.kind) {
5286 case CXCursor_ObjCSuperClassRef:
5287 return getCursorObjCSuperClassRef(C).second;
5288
5289 case CXCursor_ObjCProtocolRef:
5290 return getCursorObjCProtocolRef(C).second;
5291
5292 case CXCursor_ObjCClassRef:
5293 return getCursorObjCClassRef(C).second;
5294
5295 case CXCursor_TypeRef:
5296 return getCursorTypeRef(C).second;
5297
5298 case CXCursor_TemplateRef:
5299 return getCursorTemplateRef(C).second;
5300
5301 case CXCursor_NamespaceRef:
5302 return getCursorNamespaceRef(C).second;
5303
5304 case CXCursor_MemberRef:
5305 return getCursorMemberRef(C).second;
5306
5307 case CXCursor_CXXBaseSpecifier:
5308 return getCursorCXXBaseSpecifier(C)->getSourceRange();
5309
5310 case CXCursor_LabelRef:
5311 return getCursorLabelRef(C).second;
5312
5313 case CXCursor_OverloadedDeclRef:
5314 return getCursorOverloadedDeclRef(C).second;
5315
5316 case CXCursor_VariableRef:
5317 return getCursorVariableRef(C).second;
5318
5319 default:
5320 // FIXME: Need a way to enumerate all non-reference cases.
5321 llvm_unreachable("Missed a reference kind");
5322 }
5323 }
5324
5325 if (clang_isExpression(C.kind))
5326 return getCursorExpr(C)->getSourceRange();
5327
5328 if (clang_isStatement(C.kind))
5329 return getCursorStmt(C)->getSourceRange();
5330
5331 if (clang_isAttribute(C.kind))
5332 return getCursorAttr(C)->getRange();
5333
5334 if (C.kind == CXCursor_PreprocessingDirective)
5335 return cxcursor::getCursorPreprocessingDirective(C);
5336
5337 if (C.kind == CXCursor_MacroExpansion) {
5338 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005339 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005340 return TU->mapRangeFromPreamble(Range);
5341 }
5342
5343 if (C.kind == CXCursor_MacroDefinition) {
5344 ASTUnit *TU = getCursorASTUnit(C);
5345 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
5346 return TU->mapRangeFromPreamble(Range);
5347 }
5348
5349 if (C.kind == CXCursor_InclusionDirective) {
5350 ASTUnit *TU = getCursorASTUnit(C);
5351 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
5352 return TU->mapRangeFromPreamble(Range);
5353 }
5354
5355 if (C.kind == CXCursor_TranslationUnit) {
5356 ASTUnit *TU = getCursorASTUnit(C);
5357 FileID MainID = TU->getSourceManager().getMainFileID();
5358 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
5359 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
5360 return SourceRange(Start, End);
5361 }
5362
5363 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005364 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005365 if (!D)
5366 return SourceRange();
5367
5368 SourceRange R = D->getSourceRange();
5369 // FIXME: Multiple variables declared in a single declaration
5370 // currently lack the information needed to correctly determine their
5371 // ranges when accounting for the type-specifier. We use context
5372 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
5373 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005374 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005375 if (!cxcursor::isFirstInDeclGroup(C))
5376 R.setBegin(VD->getLocation());
5377 }
5378 return R;
5379 }
5380 return SourceRange();
5381}
5382
5383/// \brief Retrieves the "raw" cursor extent, which is then extended to include
5384/// the decl-specifier-seq for declarations.
5385static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
5386 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005387 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005388 if (!D)
5389 return SourceRange();
5390
5391 SourceRange R = D->getSourceRange();
5392
5393 // Adjust the start of the location for declarations preceded by
5394 // declaration specifiers.
5395 SourceLocation StartLoc;
5396 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
5397 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
5398 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005399 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005400 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
5401 StartLoc = TI->getTypeLoc().getLocStart();
5402 }
5403
5404 if (StartLoc.isValid() && R.getBegin().isValid() &&
5405 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
5406 R.setBegin(StartLoc);
5407
5408 // FIXME: Multiple variables declared in a single declaration
5409 // currently lack the information needed to correctly determine their
5410 // ranges when accounting for the type-specifier. We use context
5411 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
5412 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005413 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005414 if (!cxcursor::isFirstInDeclGroup(C))
5415 R.setBegin(VD->getLocation());
5416 }
5417
5418 return R;
5419 }
5420
5421 return getRawCursorExtent(C);
5422}
5423
5424extern "C" {
5425
5426CXSourceRange clang_getCursorExtent(CXCursor C) {
5427 SourceRange R = getRawCursorExtent(C);
5428 if (R.isInvalid())
5429 return clang_getNullRange();
5430
5431 return cxloc::translateSourceRange(getCursorContext(C), R);
5432}
5433
5434CXCursor clang_getCursorReferenced(CXCursor C) {
5435 if (clang_isInvalid(C.kind))
5436 return clang_getNullCursor();
5437
5438 CXTranslationUnit tu = getCursorTU(C);
5439 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005440 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005441 if (!D)
5442 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005443 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005444 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005445 if (const ObjCPropertyImplDecl *PropImpl =
5446 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005447 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
5448 return MakeCXCursor(Property, tu);
5449
5450 return C;
5451 }
5452
5453 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005454 const Expr *E = getCursorExpr(C);
5455 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00005456 if (D) {
5457 CXCursor declCursor = MakeCXCursor(D, tu);
5458 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
5459 declCursor);
5460 return declCursor;
5461 }
5462
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005463 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00005464 return MakeCursorOverloadedDeclRef(Ovl, tu);
5465
5466 return clang_getNullCursor();
5467 }
5468
5469 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005470 const Stmt *S = getCursorStmt(C);
5471 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00005472 if (LabelDecl *label = Goto->getLabel())
5473 if (LabelStmt *labelS = label->getStmt())
5474 return MakeCXCursor(labelS, getCursorDecl(C), tu);
5475
5476 return clang_getNullCursor();
5477 }
Richard Smith66a81862015-05-04 02:25:31 +00005478
Guy Benyei11169dd2012-12-18 14:30:41 +00005479 if (C.kind == CXCursor_MacroExpansion) {
Richard Smith66a81862015-05-04 02:25:31 +00005480 if (const MacroDefinitionRecord *Def =
5481 getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005482 return MakeMacroDefinitionCursor(Def, tu);
5483 }
5484
5485 if (!clang_isReference(C.kind))
5486 return clang_getNullCursor();
5487
5488 switch (C.kind) {
5489 case CXCursor_ObjCSuperClassRef:
5490 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
5491
5492 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005493 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
5494 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005495 return MakeCXCursor(Def, tu);
5496
5497 return MakeCXCursor(Prot, tu);
5498 }
5499
5500 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005501 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
5502 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005503 return MakeCXCursor(Def, tu);
5504
5505 return MakeCXCursor(Class, tu);
5506 }
5507
5508 case CXCursor_TypeRef:
5509 return MakeCXCursor(getCursorTypeRef(C).first, tu );
5510
5511 case CXCursor_TemplateRef:
5512 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
5513
5514 case CXCursor_NamespaceRef:
5515 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
5516
5517 case CXCursor_MemberRef:
5518 return MakeCXCursor(getCursorMemberRef(C).first, tu );
5519
5520 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005521 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005522 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
5523 tu ));
5524 }
5525
5526 case CXCursor_LabelRef:
5527 // FIXME: We end up faking the "parent" declaration here because we
5528 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005529 return MakeCXCursor(getCursorLabelRef(C).first,
5530 cxtu::getASTUnit(tu)->getASTContext()
5531 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00005532 tu);
5533
5534 case CXCursor_OverloadedDeclRef:
5535 return C;
5536
5537 case CXCursor_VariableRef:
5538 return MakeCXCursor(getCursorVariableRef(C).first, tu);
5539
5540 default:
5541 // We would prefer to enumerate all non-reference cursor kinds here.
5542 llvm_unreachable("Unhandled reference cursor kind");
5543 }
5544}
5545
5546CXCursor clang_getCursorDefinition(CXCursor C) {
5547 if (clang_isInvalid(C.kind))
5548 return clang_getNullCursor();
5549
5550 CXTranslationUnit TU = getCursorTU(C);
5551
5552 bool WasReference = false;
5553 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
5554 C = clang_getCursorReferenced(C);
5555 WasReference = true;
5556 }
5557
5558 if (C.kind == CXCursor_MacroExpansion)
5559 return clang_getCursorReferenced(C);
5560
5561 if (!clang_isDeclaration(C.kind))
5562 return clang_getNullCursor();
5563
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005564 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005565 if (!D)
5566 return clang_getNullCursor();
5567
5568 switch (D->getKind()) {
5569 // Declaration kinds that don't really separate the notions of
5570 // declaration and definition.
5571 case Decl::Namespace:
5572 case Decl::Typedef:
5573 case Decl::TypeAlias:
5574 case Decl::TypeAliasTemplate:
5575 case Decl::TemplateTypeParm:
5576 case Decl::EnumConstant:
5577 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00005578 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005579 case Decl::IndirectField:
5580 case Decl::ObjCIvar:
5581 case Decl::ObjCAtDefsField:
5582 case Decl::ImplicitParam:
5583 case Decl::ParmVar:
5584 case Decl::NonTypeTemplateParm:
5585 case Decl::TemplateTemplateParm:
5586 case Decl::ObjCCategoryImpl:
5587 case Decl::ObjCImplementation:
5588 case Decl::AccessSpec:
5589 case Decl::LinkageSpec:
5590 case Decl::ObjCPropertyImpl:
5591 case Decl::FileScopeAsm:
5592 case Decl::StaticAssert:
5593 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00005594 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00005595 case Decl::Label: // FIXME: Is this right??
5596 case Decl::ClassScopeFunctionSpecialization:
5597 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00005598 case Decl::OMPThreadPrivate:
Douglas Gregor85f3f952015-07-07 03:57:15 +00005599 case Decl::ObjCTypeParam:
David Majnemerd9b1a4f2015-11-04 03:40:30 +00005600 case Decl::BuiltinTemplate:
Guy Benyei11169dd2012-12-18 14:30:41 +00005601 return C;
5602
5603 // Declaration kinds that don't make any sense here, but are
5604 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00005605 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005606 case Decl::TranslationUnit:
Richard Smithf19e1272015-03-07 00:04:49 +00005607 case Decl::ExternCContext:
Guy Benyei11169dd2012-12-18 14:30:41 +00005608 break;
5609
5610 // Declaration kinds for which the definition is not resolvable.
5611 case Decl::UnresolvedUsingTypename:
5612 case Decl::UnresolvedUsingValue:
5613 break;
5614
5615 case Decl::UsingDirective:
5616 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
5617 TU);
5618
5619 case Decl::NamespaceAlias:
5620 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
5621
5622 case Decl::Enum:
5623 case Decl::Record:
5624 case Decl::CXXRecord:
5625 case Decl::ClassTemplateSpecialization:
5626 case Decl::ClassTemplatePartialSpecialization:
5627 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
5628 return MakeCXCursor(Def, TU);
5629 return clang_getNullCursor();
5630
5631 case Decl::Function:
5632 case Decl::CXXMethod:
5633 case Decl::CXXConstructor:
5634 case Decl::CXXDestructor:
5635 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00005636 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005637 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00005638 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005639 return clang_getNullCursor();
5640 }
5641
Larisse Voufo39a1e502013-08-06 01:03:05 +00005642 case Decl::Var:
5643 case Decl::VarTemplateSpecialization:
5644 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00005645 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005646 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005647 return MakeCXCursor(Def, TU);
5648 return clang_getNullCursor();
5649 }
5650
5651 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00005652 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005653 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
5654 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
5655 return clang_getNullCursor();
5656 }
5657
5658 case Decl::ClassTemplate: {
5659 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
5660 ->getDefinition())
5661 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
5662 TU);
5663 return clang_getNullCursor();
5664 }
5665
Larisse Voufo39a1e502013-08-06 01:03:05 +00005666 case Decl::VarTemplate: {
5667 if (VarDecl *Def =
5668 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
5669 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
5670 return clang_getNullCursor();
5671 }
5672
Guy Benyei11169dd2012-12-18 14:30:41 +00005673 case Decl::Using:
5674 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
5675 D->getLocation(), TU);
5676
5677 case Decl::UsingShadow:
5678 return clang_getCursorDefinition(
5679 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
5680 TU));
5681
5682 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005683 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005684 if (Method->isThisDeclarationADefinition())
5685 return C;
5686
5687 // Dig out the method definition in the associated
5688 // @implementation, if we have it.
5689 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005690 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005691 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
5692 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
5693 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
5694 Method->isInstanceMethod()))
5695 if (Def->isThisDeclarationADefinition())
5696 return MakeCXCursor(Def, TU);
5697
5698 return clang_getNullCursor();
5699 }
5700
5701 case Decl::ObjCCategory:
5702 if (ObjCCategoryImplDecl *Impl
5703 = cast<ObjCCategoryDecl>(D)->getImplementation())
5704 return MakeCXCursor(Impl, TU);
5705 return clang_getNullCursor();
5706
5707 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005708 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005709 return MakeCXCursor(Def, TU);
5710 return clang_getNullCursor();
5711
5712 case Decl::ObjCInterface: {
5713 // There are two notions of a "definition" for an Objective-C
5714 // class: the interface and its implementation. When we resolved a
5715 // reference to an Objective-C class, produce the @interface as
5716 // the definition; when we were provided with the interface,
5717 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005718 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005719 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005720 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005721 return MakeCXCursor(Def, TU);
5722 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
5723 return MakeCXCursor(Impl, TU);
5724 return clang_getNullCursor();
5725 }
5726
5727 case Decl::ObjCProperty:
5728 // FIXME: We don't really know where to find the
5729 // ObjCPropertyImplDecls that implement this property.
5730 return clang_getNullCursor();
5731
5732 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005733 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005734 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005735 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005736 return MakeCXCursor(Def, TU);
5737
5738 return clang_getNullCursor();
5739
5740 case Decl::Friend:
5741 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
5742 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5743 return clang_getNullCursor();
5744
5745 case Decl::FriendTemplate:
5746 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
5747 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5748 return clang_getNullCursor();
5749 }
5750
5751 return clang_getNullCursor();
5752}
5753
5754unsigned clang_isCursorDefinition(CXCursor C) {
5755 if (!clang_isDeclaration(C.kind))
5756 return 0;
5757
5758 return clang_getCursorDefinition(C) == C;
5759}
5760
5761CXCursor clang_getCanonicalCursor(CXCursor C) {
5762 if (!clang_isDeclaration(C.kind))
5763 return C;
5764
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005765 if (const Decl *D = getCursorDecl(C)) {
5766 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005767 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5768 return MakeCXCursor(CatD, getCursorTU(C));
5769
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005770 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5771 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00005772 return MakeCXCursor(IFD, getCursorTU(C));
5773
5774 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5775 }
5776
5777 return C;
5778}
5779
5780int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5781 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5782}
5783
5784unsigned clang_getNumOverloadedDecls(CXCursor C) {
5785 if (C.kind != CXCursor_OverloadedDeclRef)
5786 return 0;
5787
5788 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005789 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005790 return E->getNumDecls();
5791
5792 if (OverloadedTemplateStorage *S
5793 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5794 return S->size();
5795
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005796 const Decl *D = Storage.get<const Decl *>();
5797 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005798 return Using->shadow_size();
5799
5800 return 0;
5801}
5802
5803CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5804 if (cursor.kind != CXCursor_OverloadedDeclRef)
5805 return clang_getNullCursor();
5806
5807 if (index >= clang_getNumOverloadedDecls(cursor))
5808 return clang_getNullCursor();
5809
5810 CXTranslationUnit TU = getCursorTU(cursor);
5811 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005812 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005813 return MakeCXCursor(E->decls_begin()[index], TU);
5814
5815 if (OverloadedTemplateStorage *S
5816 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5817 return MakeCXCursor(S->begin()[index], TU);
5818
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005819 const Decl *D = Storage.get<const Decl *>();
5820 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005821 // FIXME: This is, unfortunately, linear time.
5822 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5823 std::advance(Pos, index);
5824 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5825 }
5826
5827 return clang_getNullCursor();
5828}
5829
5830void clang_getDefinitionSpellingAndExtent(CXCursor C,
5831 const char **startBuf,
5832 const char **endBuf,
5833 unsigned *startLine,
5834 unsigned *startColumn,
5835 unsigned *endLine,
5836 unsigned *endColumn) {
5837 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005838 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005839 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5840
5841 SourceManager &SM = FD->getASTContext().getSourceManager();
5842 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5843 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5844 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5845 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5846 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5847 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5848}
5849
5850
5851CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5852 unsigned PieceIndex) {
5853 RefNamePieces Pieces;
5854
5855 switch (C.kind) {
5856 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005857 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005858 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5859 E->getQualifierLoc().getSourceRange());
5860 break;
5861
5862 case CXCursor_DeclRefExpr:
James Y Knight04ec5bf2015-12-24 02:59:37 +00005863 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C))) {
5864 SourceRange TemplateArgLoc(E->getLAngleLoc(), E->getRAngleLoc());
5865 Pieces =
5866 buildPieces(NameFlags, false, E->getNameInfo(),
5867 E->getQualifierLoc().getSourceRange(), &TemplateArgLoc);
5868 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005869 break;
5870
5871 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005872 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005873 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005874 const Expr *Callee = OCE->getCallee();
5875 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005876 Callee = ICE->getSubExpr();
5877
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005878 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005879 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5880 DRE->getQualifierLoc().getSourceRange());
5881 }
5882 break;
5883
5884 default:
5885 break;
5886 }
5887
5888 if (Pieces.empty()) {
5889 if (PieceIndex == 0)
5890 return clang_getCursorExtent(C);
5891 } else if (PieceIndex < Pieces.size()) {
5892 SourceRange R = Pieces[PieceIndex];
5893 if (R.isValid())
5894 return cxloc::translateSourceRange(getCursorContext(C), R);
5895 }
5896
5897 return clang_getNullRange();
5898}
5899
5900void clang_enableStackTraces(void) {
5901 llvm::sys::PrintStackTraceOnErrorSignal();
5902}
5903
5904void clang_executeOnThread(void (*fn)(void*), void *user_data,
5905 unsigned stack_size) {
5906 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5907}
5908
5909} // end: extern "C"
5910
5911//===----------------------------------------------------------------------===//
5912// Token-based Operations.
5913//===----------------------------------------------------------------------===//
5914
5915/* CXToken layout:
5916 * int_data[0]: a CXTokenKind
5917 * int_data[1]: starting token location
5918 * int_data[2]: token length
5919 * int_data[3]: reserved
5920 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5921 * otherwise unused.
5922 */
5923extern "C" {
5924
5925CXTokenKind clang_getTokenKind(CXToken CXTok) {
5926 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5927}
5928
5929CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5930 switch (clang_getTokenKind(CXTok)) {
5931 case CXToken_Identifier:
5932 case CXToken_Keyword:
5933 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005934 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005935 ->getNameStart());
5936
5937 case CXToken_Literal: {
5938 // We have stashed the starting pointer in the ptr_data field. Use it.
5939 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005940 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005941 }
5942
5943 case CXToken_Punctuation:
5944 case CXToken_Comment:
5945 break;
5946 }
5947
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005948 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005949 LOG_BAD_TU(TU);
5950 return cxstring::createEmpty();
5951 }
5952
Guy Benyei11169dd2012-12-18 14:30:41 +00005953 // We have to find the starting buffer pointer the hard way, by
5954 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005955 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005956 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005957 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005958
5959 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5960 std::pair<FileID, unsigned> LocInfo
5961 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5962 bool Invalid = false;
5963 StringRef Buffer
5964 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5965 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005966 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005967
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005968 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005969}
5970
5971CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005972 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005973 LOG_BAD_TU(TU);
5974 return clang_getNullLocation();
5975 }
5976
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005977 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005978 if (!CXXUnit)
5979 return clang_getNullLocation();
5980
5981 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5982 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5983}
5984
5985CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005986 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005987 LOG_BAD_TU(TU);
5988 return clang_getNullRange();
5989 }
5990
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005991 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005992 if (!CXXUnit)
5993 return clang_getNullRange();
5994
5995 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5996 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5997}
5998
5999static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
6000 SmallVectorImpl<CXToken> &CXTokens) {
6001 SourceManager &SourceMgr = CXXUnit->getSourceManager();
6002 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006003 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00006004 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006005 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00006006
6007 // Cannot tokenize across files.
6008 if (BeginLocInfo.first != EndLocInfo.first)
6009 return;
6010
6011 // Create a lexer
6012 bool Invalid = false;
6013 StringRef Buffer
6014 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
6015 if (Invalid)
6016 return;
6017
6018 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
6019 CXXUnit->getASTContext().getLangOpts(),
6020 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
6021 Lex.SetCommentRetentionState(true);
6022
6023 // Lex tokens until we hit the end of the range.
6024 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
6025 Token Tok;
6026 bool previousWasAt = false;
6027 do {
6028 // Lex the next token
6029 Lex.LexFromRawLexer(Tok);
6030 if (Tok.is(tok::eof))
6031 break;
6032
6033 // Initialize the CXToken.
6034 CXToken CXTok;
6035
6036 // - Common fields
6037 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
6038 CXTok.int_data[2] = Tok.getLength();
6039 CXTok.int_data[3] = 0;
6040
6041 // - Kind-specific fields
6042 if (Tok.isLiteral()) {
6043 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006044 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00006045 } else if (Tok.is(tok::raw_identifier)) {
6046 // Lookup the identifier to determine whether we have a keyword.
6047 IdentifierInfo *II
6048 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
6049
6050 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
6051 CXTok.int_data[0] = CXToken_Keyword;
6052 }
6053 else {
6054 CXTok.int_data[0] = Tok.is(tok::identifier)
6055 ? CXToken_Identifier
6056 : CXToken_Keyword;
6057 }
6058 CXTok.ptr_data = II;
6059 } else if (Tok.is(tok::comment)) {
6060 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00006061 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006062 } else {
6063 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00006064 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006065 }
6066 CXTokens.push_back(CXTok);
6067 previousWasAt = Tok.is(tok::at);
6068 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
6069}
6070
6071void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
6072 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006073 LOG_FUNC_SECTION {
6074 *Log << TU << ' ' << Range;
6075 }
6076
Guy Benyei11169dd2012-12-18 14:30:41 +00006077 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00006078 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006079 if (NumTokens)
6080 *NumTokens = 0;
6081
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006082 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006083 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00006084 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006085 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00006086
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006087 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006088 if (!CXXUnit || !Tokens || !NumTokens)
6089 return;
6090
6091 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
6092
6093 SourceRange R = cxloc::translateCXSourceRange(Range);
6094 if (R.isInvalid())
6095 return;
6096
6097 SmallVector<CXToken, 32> CXTokens;
6098 getTokens(CXXUnit, R, CXTokens);
6099
6100 if (CXTokens.empty())
6101 return;
6102
6103 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
6104 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
6105 *NumTokens = CXTokens.size();
6106}
6107
6108void clang_disposeTokens(CXTranslationUnit TU,
6109 CXToken *Tokens, unsigned NumTokens) {
6110 free(Tokens);
6111}
6112
6113} // end: extern "C"
6114
6115//===----------------------------------------------------------------------===//
6116// Token annotation APIs.
6117//===----------------------------------------------------------------------===//
6118
Guy Benyei11169dd2012-12-18 14:30:41 +00006119static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
6120 CXCursor parent,
6121 CXClientData client_data);
6122static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
6123 CXClientData client_data);
6124
6125namespace {
6126class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00006127 CXToken *Tokens;
6128 CXCursor *Cursors;
6129 unsigned NumTokens;
6130 unsigned TokIdx;
6131 unsigned PreprocessingTokIdx;
6132 CursorVisitor AnnotateVis;
6133 SourceManager &SrcMgr;
6134 bool HasContextSensitiveKeywords;
6135
6136 struct PostChildrenInfo {
6137 CXCursor Cursor;
6138 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006139 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006140 unsigned BeforeChildrenTokenIdx;
6141 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00006142 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006143
6144 CXToken &getTok(unsigned Idx) {
6145 assert(Idx < NumTokens);
6146 return Tokens[Idx];
6147 }
6148 const CXToken &getTok(unsigned Idx) const {
6149 assert(Idx < NumTokens);
6150 return Tokens[Idx];
6151 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006152 bool MoreTokens() const { return TokIdx < NumTokens; }
6153 unsigned NextToken() const { return TokIdx; }
6154 void AdvanceToken() { ++TokIdx; }
6155 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006156 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006157 }
6158 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006159 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006160 }
6161 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006162 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006163 }
6164
6165 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006166 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00006167 SourceRange);
6168
6169public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006170 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006171 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006172 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00006173 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006174 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00006175 AnnotateTokensVisitor, this,
6176 /*VisitPreprocessorLast=*/true,
6177 /*VisitIncludedEntities=*/false,
6178 RegionOfInterest,
6179 /*VisitDeclsOnly=*/false,
6180 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006181 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00006182 HasContextSensitiveKeywords(false) { }
6183
6184 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
6185 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
6186 bool postVisitChildren(CXCursor cursor);
6187 void AnnotateTokens();
6188
6189 /// \brief Determine whether the annotator saw any cursors that have
6190 /// context-sensitive keywords.
6191 bool hasContextSensitiveKeywords() const {
6192 return HasContextSensitiveKeywords;
6193 }
6194
6195 ~AnnotateTokensWorker() {
6196 assert(PostChildrenInfos.empty());
6197 }
6198};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00006199}
Guy Benyei11169dd2012-12-18 14:30:41 +00006200
6201void AnnotateTokensWorker::AnnotateTokens() {
6202 // Walk the AST within the region of interest, annotating tokens
6203 // along the way.
6204 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006205}
Guy Benyei11169dd2012-12-18 14:30:41 +00006206
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006207static inline void updateCursorAnnotation(CXCursor &Cursor,
6208 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006209 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00006210 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006211 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00006212}
6213
6214/// \brief It annotates and advances tokens with a cursor until the comparison
6215//// between the cursor location and the source range is the same as
6216/// \arg compResult.
6217///
6218/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
6219/// Pass RangeOverlap to annotate tokens inside a range.
6220void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
6221 RangeComparisonResult compResult,
6222 SourceRange range) {
6223 while (MoreTokens()) {
6224 const unsigned I = NextToken();
6225 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006226 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
6227 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00006228
6229 SourceLocation TokLoc = GetTokenLoc(I);
6230 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006231 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00006232 AdvanceToken();
6233 continue;
6234 }
6235 break;
6236 }
6237}
6238
6239/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006240/// \returns true if it advanced beyond all macro tokens, false otherwise.
6241bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00006242 CXCursor updateC,
6243 RangeComparisonResult compResult,
6244 SourceRange range) {
6245 assert(MoreTokens());
6246 assert(isFunctionMacroToken(NextToken()) &&
6247 "Should be called only for macro arg tokens");
6248
6249 // This works differently than annotateAndAdvanceTokens; because expanded
6250 // macro arguments can have arbitrary translation-unit source order, we do not
6251 // advance the token index one by one until a token fails the range test.
6252 // We only advance once past all of the macro arg tokens if all of them
6253 // pass the range test. If one of them fails we keep the token index pointing
6254 // at the start of the macro arg tokens so that the failing token will be
6255 // annotated by a subsequent annotation try.
6256
6257 bool atLeastOneCompFail = false;
6258
6259 unsigned I = NextToken();
6260 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
6261 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
6262 if (TokLoc.isFileID())
6263 continue; // not macro arg token, it's parens or comma.
6264 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
6265 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
6266 Cursors[I] = updateC;
6267 } else
6268 atLeastOneCompFail = true;
6269 }
6270
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006271 if (atLeastOneCompFail)
6272 return false;
6273
6274 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
6275 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00006276}
6277
6278enum CXChildVisitResult
6279AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006280 SourceRange cursorRange = getRawCursorExtent(cursor);
6281 if (cursorRange.isInvalid())
6282 return CXChildVisit_Recurse;
6283
6284 if (!HasContextSensitiveKeywords) {
6285 // Objective-C properties can have context-sensitive keywords.
6286 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006287 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006288 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
6289 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
6290 }
6291 // Objective-C methods can have context-sensitive keywords.
6292 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
6293 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006294 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00006295 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
6296 if (Method->getObjCDeclQualifier())
6297 HasContextSensitiveKeywords = true;
6298 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00006299 for (const auto *P : Method->params()) {
6300 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006301 HasContextSensitiveKeywords = true;
6302 break;
6303 }
6304 }
6305 }
6306 }
6307 }
6308 // C++ methods can have context-sensitive keywords.
6309 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006310 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00006311 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
6312 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
6313 HasContextSensitiveKeywords = true;
6314 }
6315 }
6316 // C++ classes can have context-sensitive keywords.
6317 else if (cursor.kind == CXCursor_StructDecl ||
6318 cursor.kind == CXCursor_ClassDecl ||
6319 cursor.kind == CXCursor_ClassTemplate ||
6320 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006321 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006322 if (D->hasAttr<FinalAttr>())
6323 HasContextSensitiveKeywords = true;
6324 }
6325 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00006326
6327 // Don't override a property annotation with its getter/setter method.
6328 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
6329 parent.kind == CXCursor_ObjCPropertyDecl)
6330 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00006331
6332 if (clang_isPreprocessing(cursor.kind)) {
6333 // Items in the preprocessing record are kept separate from items in
6334 // declarations, so we keep a separate token index.
6335 unsigned SavedTokIdx = TokIdx;
6336 TokIdx = PreprocessingTokIdx;
6337
6338 // Skip tokens up until we catch up to the beginning of the preprocessing
6339 // entry.
6340 while (MoreTokens()) {
6341 const unsigned I = NextToken();
6342 SourceLocation TokLoc = GetTokenLoc(I);
6343 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
6344 case RangeBefore:
6345 AdvanceToken();
6346 continue;
6347 case RangeAfter:
6348 case RangeOverlap:
6349 break;
6350 }
6351 break;
6352 }
6353
6354 // Look at all of the tokens within this range.
6355 while (MoreTokens()) {
6356 const unsigned I = NextToken();
6357 SourceLocation TokLoc = GetTokenLoc(I);
6358 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
6359 case RangeBefore:
6360 llvm_unreachable("Infeasible");
6361 case RangeAfter:
6362 break;
6363 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006364 // For macro expansions, just note where the beginning of the macro
6365 // expansion occurs.
6366 if (cursor.kind == CXCursor_MacroExpansion) {
6367 if (TokLoc == cursorRange.getBegin())
6368 Cursors[I] = cursor;
6369 AdvanceToken();
6370 break;
6371 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006372 // We may have already annotated macro names inside macro definitions.
6373 if (Cursors[I].kind != CXCursor_MacroExpansion)
6374 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00006375 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00006376 continue;
6377 }
6378 break;
6379 }
6380
6381 // Save the preprocessing token index; restore the non-preprocessing
6382 // token index.
6383 PreprocessingTokIdx = TokIdx;
6384 TokIdx = SavedTokIdx;
6385 return CXChildVisit_Recurse;
6386 }
6387
6388 if (cursorRange.isInvalid())
6389 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006390
6391 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00006392 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006393 const enum CXCursorKind K = clang_getCursorKind(parent);
6394 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006395 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
6396 // Attributes are annotated out-of-order, skip tokens until we reach it.
6397 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00006398 ? clang_getNullCursor() : parent;
6399
6400 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
6401
6402 // Avoid having the cursor of an expression "overwrite" the annotation of the
6403 // variable declaration that it belongs to.
6404 // This can happen for C++ constructor expressions whose range generally
6405 // include the variable declaration, e.g.:
6406 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006407 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00006408 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00006409 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006410 const unsigned I = NextToken();
6411 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
6412 E->getLocStart() == D->getLocation() &&
6413 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006414 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00006415 AdvanceToken();
6416 }
6417 }
6418 }
6419
6420 // Before recursing into the children keep some state that we are going
6421 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
6422 // extra work after the child nodes are visited.
6423 // Note that we don't call VisitChildren here to avoid traversing statements
6424 // code-recursively which can blow the stack.
6425
6426 PostChildrenInfo Info;
6427 Info.Cursor = cursor;
6428 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006429 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006430 Info.BeforeChildrenTokenIdx = NextToken();
6431 PostChildrenInfos.push_back(Info);
6432
6433 return CXChildVisit_Recurse;
6434}
6435
6436bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
6437 if (PostChildrenInfos.empty())
6438 return false;
6439 const PostChildrenInfo &Info = PostChildrenInfos.back();
6440 if (!clang_equalCursors(Info.Cursor, cursor))
6441 return false;
6442
6443 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
6444 const unsigned AfterChildren = NextToken();
6445 SourceRange cursorRange = Info.CursorRange;
6446
6447 // Scan the tokens that are at the end of the cursor, but are not captured
6448 // but the child cursors.
6449 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
6450
6451 // Scan the tokens that are at the beginning of the cursor, but are not
6452 // capture by the child cursors.
6453 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
6454 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
6455 break;
6456
6457 Cursors[I] = cursor;
6458 }
6459
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006460 // Attributes are annotated out-of-order, rewind TokIdx to when we first
6461 // encountered the attribute cursor.
6462 if (clang_isAttribute(cursor.kind))
6463 TokIdx = Info.BeforeReachingCursorIdx;
6464
Guy Benyei11169dd2012-12-18 14:30:41 +00006465 PostChildrenInfos.pop_back();
6466 return false;
6467}
6468
6469static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
6470 CXCursor parent,
6471 CXClientData client_data) {
6472 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
6473}
6474
6475static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
6476 CXClientData client_data) {
6477 return static_cast<AnnotateTokensWorker*>(client_data)->
6478 postVisitChildren(cursor);
6479}
6480
6481namespace {
6482
6483/// \brief Uses the macro expansions in the preprocessing record to find
6484/// and mark tokens that are macro arguments. This info is used by the
6485/// AnnotateTokensWorker.
6486class MarkMacroArgTokensVisitor {
6487 SourceManager &SM;
6488 CXToken *Tokens;
6489 unsigned NumTokens;
6490 unsigned CurIdx;
6491
6492public:
6493 MarkMacroArgTokensVisitor(SourceManager &SM,
6494 CXToken *tokens, unsigned numTokens)
6495 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
6496
6497 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
6498 if (cursor.kind != CXCursor_MacroExpansion)
6499 return CXChildVisit_Continue;
6500
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006501 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00006502 if (macroRange.getBegin() == macroRange.getEnd())
6503 return CXChildVisit_Continue; // it's not a function macro.
6504
6505 for (; CurIdx < NumTokens; ++CurIdx) {
6506 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
6507 macroRange.getBegin()))
6508 break;
6509 }
6510
6511 if (CurIdx == NumTokens)
6512 return CXChildVisit_Break;
6513
6514 for (; CurIdx < NumTokens; ++CurIdx) {
6515 SourceLocation tokLoc = getTokenLoc(CurIdx);
6516 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
6517 break;
6518
6519 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
6520 }
6521
6522 if (CurIdx == NumTokens)
6523 return CXChildVisit_Break;
6524
6525 return CXChildVisit_Continue;
6526 }
6527
6528private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006529 CXToken &getTok(unsigned Idx) {
6530 assert(Idx < NumTokens);
6531 return Tokens[Idx];
6532 }
6533 const CXToken &getTok(unsigned Idx) const {
6534 assert(Idx < NumTokens);
6535 return Tokens[Idx];
6536 }
6537
Guy Benyei11169dd2012-12-18 14:30:41 +00006538 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006539 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006540 }
6541
6542 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
6543 // The third field is reserved and currently not used. Use it here
6544 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006545 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00006546 }
6547};
6548
6549} // end anonymous namespace
6550
6551static CXChildVisitResult
6552MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
6553 CXClientData client_data) {
6554 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
6555 parent);
6556}
6557
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006558/// \brief Used by \c annotatePreprocessorTokens.
6559/// \returns true if lexing was finished, false otherwise.
6560static bool lexNext(Lexer &Lex, Token &Tok,
6561 unsigned &NextIdx, unsigned NumTokens) {
6562 if (NextIdx >= NumTokens)
6563 return true;
6564
6565 ++NextIdx;
6566 Lex.LexFromRawLexer(Tok);
Alexander Kornienko1a9f1842015-12-28 15:24:08 +00006567 return Tok.is(tok::eof);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006568}
6569
Guy Benyei11169dd2012-12-18 14:30:41 +00006570static void annotatePreprocessorTokens(CXTranslationUnit TU,
6571 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006572 CXCursor *Cursors,
6573 CXToken *Tokens,
6574 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006575 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006576
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006577 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00006578 SourceManager &SourceMgr = CXXUnit->getSourceManager();
6579 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006580 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00006581 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006582 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00006583
6584 if (BeginLocInfo.first != EndLocInfo.first)
6585 return;
6586
6587 StringRef Buffer;
6588 bool Invalid = false;
6589 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
6590 if (Buffer.empty() || Invalid)
6591 return;
6592
6593 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
6594 CXXUnit->getASTContext().getLangOpts(),
6595 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
6596 Buffer.end());
6597 Lex.SetCommentRetentionState(true);
6598
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006599 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006600 // Lex tokens in raw mode until we hit the end of the range, to avoid
6601 // entering #includes or expanding macros.
6602 while (true) {
6603 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006604 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6605 break;
6606 unsigned TokIdx = NextIdx-1;
6607 assert(Tok.getLocation() ==
6608 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006609
6610 reprocess:
6611 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006612 // We have found a preprocessing directive. Annotate the tokens
6613 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00006614 //
6615 // FIXME: Some simple tests here could identify macro definitions and
6616 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006617
6618 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006619 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6620 break;
6621
Craig Topper69186e72014-06-08 08:38:04 +00006622 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00006623 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006624 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6625 break;
6626
6627 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00006628 IdentifierInfo &II =
6629 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006630 SourceLocation MappedTokLoc =
6631 CXXUnit->mapLocationToPreamble(Tok.getLocation());
6632 MI = getMacroInfo(II, MappedTokLoc, TU);
6633 }
6634 }
6635
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006636 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00006637 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006638 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
6639 finished = true;
6640 break;
6641 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006642 // If we are in a macro definition, check if the token was ever a
6643 // macro name and annotate it if that's the case.
6644 if (MI) {
6645 SourceLocation SaveLoc = Tok.getLocation();
6646 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
Richard Smith66a81862015-05-04 02:25:31 +00006647 MacroDefinitionRecord *MacroDef =
6648 checkForMacroInMacroDefinition(MI, Tok, TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006649 Tok.setLocation(SaveLoc);
6650 if (MacroDef)
Richard Smith66a81862015-05-04 02:25:31 +00006651 Cursors[NextIdx - 1] =
6652 MakeMacroExpansionCursor(MacroDef, Tok.getLocation(), TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006653 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006654 } while (!Tok.isAtStartOfLine());
6655
6656 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
6657 assert(TokIdx <= LastIdx);
6658 SourceLocation EndLoc =
6659 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
6660 CXCursor Cursor =
6661 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
6662
6663 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006664 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006665
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006666 if (finished)
6667 break;
6668 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00006669 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006670 }
6671}
6672
6673// This gets run a separate thread to avoid stack blowout.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006674static void clang_annotateTokensImpl(CXTranslationUnit TU, ASTUnit *CXXUnit,
6675 CXToken *Tokens, unsigned NumTokens,
6676 CXCursor *Cursors) {
Dmitri Gribenko183436e2013-01-26 21:49:50 +00006677 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006678 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
6679 setThreadBackgroundPriority();
6680
6681 // Determine the region of interest, which contains all of the tokens.
6682 SourceRange RegionOfInterest;
6683 RegionOfInterest.setBegin(
6684 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
6685 RegionOfInterest.setEnd(
6686 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
6687 Tokens[NumTokens-1])));
6688
Guy Benyei11169dd2012-12-18 14:30:41 +00006689 // Relex the tokens within the source range to look for preprocessing
6690 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006691 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006692
6693 // If begin location points inside a macro argument, set it to the expansion
6694 // location so we can have the full context when annotating semantically.
6695 {
6696 SourceManager &SM = CXXUnit->getSourceManager();
6697 SourceLocation Loc =
6698 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
6699 if (Loc.isMacroID())
6700 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
6701 }
6702
Guy Benyei11169dd2012-12-18 14:30:41 +00006703 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
6704 // Search and mark tokens that are macro argument expansions.
6705 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
6706 Tokens, NumTokens);
6707 CursorVisitor MacroArgMarker(TU,
6708 MarkMacroArgTokensVisitorDelegate, &Visitor,
6709 /*VisitPreprocessorLast=*/true,
6710 /*VisitIncludedEntities=*/false,
6711 RegionOfInterest);
6712 MacroArgMarker.visitPreprocessedEntitiesInRegion();
6713 }
6714
6715 // Annotate all of the source locations in the region of interest that map to
6716 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006717 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00006718
6719 // FIXME: We use a ridiculous stack size here because the data-recursion
6720 // algorithm uses a large stack frame than the non-data recursive version,
6721 // and AnnotationTokensWorker currently transforms the data-recursion
6722 // algorithm back into a traditional recursion by explicitly calling
6723 // VisitChildren(). We will need to remove this explicit recursive call.
6724 W.AnnotateTokens();
6725
6726 // If we ran into any entities that involve context-sensitive keywords,
6727 // take another pass through the tokens to mark them as such.
6728 if (W.hasContextSensitiveKeywords()) {
6729 for (unsigned I = 0; I != NumTokens; ++I) {
6730 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
6731 continue;
6732
6733 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
6734 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006735 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006736 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
6737 if (Property->getPropertyAttributesAsWritten() != 0 &&
6738 llvm::StringSwitch<bool>(II->getName())
6739 .Case("readonly", true)
6740 .Case("assign", true)
6741 .Case("unsafe_unretained", true)
6742 .Case("readwrite", true)
6743 .Case("retain", true)
6744 .Case("copy", true)
6745 .Case("nonatomic", true)
6746 .Case("atomic", true)
6747 .Case("getter", true)
6748 .Case("setter", true)
6749 .Case("strong", true)
6750 .Case("weak", true)
6751 .Default(false))
6752 Tokens[I].int_data[0] = CXToken_Keyword;
6753 }
6754 continue;
6755 }
6756
6757 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6758 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6759 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6760 if (llvm::StringSwitch<bool>(II->getName())
6761 .Case("in", true)
6762 .Case("out", true)
6763 .Case("inout", true)
6764 .Case("oneway", true)
6765 .Case("bycopy", true)
6766 .Case("byref", true)
6767 .Default(false))
6768 Tokens[I].int_data[0] = CXToken_Keyword;
6769 continue;
6770 }
6771
6772 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6773 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6774 Tokens[I].int_data[0] = CXToken_Keyword;
6775 continue;
6776 }
6777 }
6778 }
6779}
6780
6781extern "C" {
6782
6783void clang_annotateTokens(CXTranslationUnit TU,
6784 CXToken *Tokens, unsigned NumTokens,
6785 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006786 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006787 LOG_BAD_TU(TU);
6788 return;
6789 }
6790 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006791 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006792 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006793 }
6794
6795 LOG_FUNC_SECTION {
6796 *Log << TU << ' ';
6797 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6798 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6799 *Log << clang_getRange(bloc, eloc);
6800 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006801
6802 // Any token we don't specifically annotate will have a NULL cursor.
6803 CXCursor C = clang_getNullCursor();
6804 for (unsigned I = 0; I != NumTokens; ++I)
6805 Cursors[I] = C;
6806
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006807 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006808 if (!CXXUnit)
6809 return;
6810
6811 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006812
6813 auto AnnotateTokensImpl = [=]() {
6814 clang_annotateTokensImpl(TU, CXXUnit, Tokens, NumTokens, Cursors);
6815 };
Guy Benyei11169dd2012-12-18 14:30:41 +00006816 llvm::CrashRecoveryContext CRC;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006817 if (!RunSafely(CRC, AnnotateTokensImpl, GetSafetyThreadStackSize() * 2)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006818 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6819 }
6820}
6821
6822} // end: extern "C"
6823
6824//===----------------------------------------------------------------------===//
6825// Operations for querying linkage of a cursor.
6826//===----------------------------------------------------------------------===//
6827
6828extern "C" {
6829CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6830 if (!clang_isDeclaration(cursor.kind))
6831 return CXLinkage_Invalid;
6832
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006833 const Decl *D = cxcursor::getCursorDecl(cursor);
6834 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006835 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006836 case NoLinkage:
6837 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006838 case InternalLinkage: return CXLinkage_Internal;
6839 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6840 case ExternalLinkage: return CXLinkage_External;
6841 };
6842
6843 return CXLinkage_Invalid;
6844}
6845} // end: extern "C"
6846
6847//===----------------------------------------------------------------------===//
Ehsan Akhgari93697fa2015-11-23 19:56:46 +00006848// Operations for querying visibility of a cursor.
6849//===----------------------------------------------------------------------===//
6850
6851extern "C" {
6852CXVisibilityKind clang_getCursorVisibility(CXCursor cursor) {
6853 if (!clang_isDeclaration(cursor.kind))
6854 return CXVisibility_Invalid;
6855
6856 const Decl *D = cxcursor::getCursorDecl(cursor);
6857 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
6858 switch (ND->getVisibility()) {
6859 case HiddenVisibility: return CXVisibility_Hidden;
6860 case ProtectedVisibility: return CXVisibility_Protected;
6861 case DefaultVisibility: return CXVisibility_Default;
6862 };
6863
6864 return CXVisibility_Invalid;
6865}
6866} // end: extern "C"
6867
6868//===----------------------------------------------------------------------===//
Guy Benyei11169dd2012-12-18 14:30:41 +00006869// Operations for querying language of a cursor.
6870//===----------------------------------------------------------------------===//
6871
6872static CXLanguageKind getDeclLanguage(const Decl *D) {
6873 if (!D)
6874 return CXLanguage_C;
6875
6876 switch (D->getKind()) {
6877 default:
6878 break;
6879 case Decl::ImplicitParam:
6880 case Decl::ObjCAtDefsField:
6881 case Decl::ObjCCategory:
6882 case Decl::ObjCCategoryImpl:
6883 case Decl::ObjCCompatibleAlias:
6884 case Decl::ObjCImplementation:
6885 case Decl::ObjCInterface:
6886 case Decl::ObjCIvar:
6887 case Decl::ObjCMethod:
6888 case Decl::ObjCProperty:
6889 case Decl::ObjCPropertyImpl:
6890 case Decl::ObjCProtocol:
Douglas Gregor85f3f952015-07-07 03:57:15 +00006891 case Decl::ObjCTypeParam:
Guy Benyei11169dd2012-12-18 14:30:41 +00006892 return CXLanguage_ObjC;
6893 case Decl::CXXConstructor:
6894 case Decl::CXXConversion:
6895 case Decl::CXXDestructor:
6896 case Decl::CXXMethod:
6897 case Decl::CXXRecord:
6898 case Decl::ClassTemplate:
6899 case Decl::ClassTemplatePartialSpecialization:
6900 case Decl::ClassTemplateSpecialization:
6901 case Decl::Friend:
6902 case Decl::FriendTemplate:
6903 case Decl::FunctionTemplate:
6904 case Decl::LinkageSpec:
6905 case Decl::Namespace:
6906 case Decl::NamespaceAlias:
6907 case Decl::NonTypeTemplateParm:
6908 case Decl::StaticAssert:
6909 case Decl::TemplateTemplateParm:
6910 case Decl::TemplateTypeParm:
6911 case Decl::UnresolvedUsingTypename:
6912 case Decl::UnresolvedUsingValue:
6913 case Decl::Using:
6914 case Decl::UsingDirective:
6915 case Decl::UsingShadow:
6916 return CXLanguage_CPlusPlus;
6917 }
6918
6919 return CXLanguage_C;
6920}
6921
6922extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006923
6924static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6925 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
Manuel Klimek8e3a7ed2015-09-25 17:53:16 +00006926 return CXAvailability_NotAvailable;
Guy Benyei11169dd2012-12-18 14:30:41 +00006927
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006928 switch (D->getAvailability()) {
6929 case AR_Available:
6930 case AR_NotYetIntroduced:
6931 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006932 return getCursorAvailabilityForDecl(
6933 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006934 return CXAvailability_Available;
6935
6936 case AR_Deprecated:
6937 return CXAvailability_Deprecated;
6938
6939 case AR_Unavailable:
6940 return CXAvailability_NotAvailable;
6941 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006942
6943 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006944}
6945
Guy Benyei11169dd2012-12-18 14:30:41 +00006946enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6947 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006948 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6949 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006950
6951 return CXAvailability_Available;
6952}
6953
6954static CXVersion convertVersion(VersionTuple In) {
6955 CXVersion Out = { -1, -1, -1 };
6956 if (In.empty())
6957 return Out;
6958
6959 Out.Major = In.getMajor();
6960
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006961 Optional<unsigned> Minor = In.getMinor();
6962 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006963 Out.Minor = *Minor;
6964 else
6965 return Out;
6966
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006967 Optional<unsigned> Subminor = In.getSubminor();
6968 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006969 Out.Subminor = *Subminor;
6970
6971 return Out;
6972}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006973
6974static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6975 int *always_deprecated,
6976 CXString *deprecated_message,
6977 int *always_unavailable,
6978 CXString *unavailable_message,
6979 CXPlatformAvailability *availability,
6980 int availability_size) {
6981 bool HadAvailAttr = false;
6982 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006983 for (auto A : D->attrs()) {
6984 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006985 HadAvailAttr = true;
6986 if (always_deprecated)
6987 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006988 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006989 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006990 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006991 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006992 continue;
6993 }
6994
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006995 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006996 HadAvailAttr = true;
6997 if (always_unavailable)
6998 *always_unavailable = 1;
6999 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00007000 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007001 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
7002 }
7003 continue;
7004 }
7005
Aaron Ballmanb97112e2014-03-08 22:19:01 +00007006 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007007 HadAvailAttr = true;
7008 if (N < availability_size) {
7009 availability[N].Platform
7010 = cxstring::createDup(Avail->getPlatform()->getName());
7011 availability[N].Introduced = convertVersion(Avail->getIntroduced());
7012 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
7013 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
7014 availability[N].Unavailable = Avail->getUnavailable();
7015 availability[N].Message = cxstring::createDup(Avail->getMessage());
7016 }
7017 ++N;
7018 }
7019 }
7020
7021 if (!HadAvailAttr)
7022 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
7023 return getCursorPlatformAvailabilityForDecl(
7024 cast<Decl>(EnumConst->getDeclContext()),
7025 always_deprecated,
7026 deprecated_message,
7027 always_unavailable,
7028 unavailable_message,
7029 availability,
7030 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00007031
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007032 return N;
7033}
7034
Guy Benyei11169dd2012-12-18 14:30:41 +00007035int clang_getCursorPlatformAvailability(CXCursor cursor,
7036 int *always_deprecated,
7037 CXString *deprecated_message,
7038 int *always_unavailable,
7039 CXString *unavailable_message,
7040 CXPlatformAvailability *availability,
7041 int availability_size) {
7042 if (always_deprecated)
7043 *always_deprecated = 0;
7044 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007045 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00007046 if (always_unavailable)
7047 *always_unavailable = 0;
7048 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007049 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007050
Guy Benyei11169dd2012-12-18 14:30:41 +00007051 if (!clang_isDeclaration(cursor.kind))
7052 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007053
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007054 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00007055 if (!D)
7056 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007057
7058 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
7059 deprecated_message,
7060 always_unavailable,
7061 unavailable_message,
7062 availability,
7063 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00007064}
7065
7066void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
7067 clang_disposeString(availability->Platform);
7068 clang_disposeString(availability->Message);
7069}
7070
7071CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
7072 if (clang_isDeclaration(cursor.kind))
7073 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
7074
7075 return CXLanguage_Invalid;
7076}
7077
7078 /// \brief If the given cursor is the "templated" declaration
7079 /// descibing a class or function template, return the class or
7080 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007081static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007082 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00007083 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007084
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007085 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00007086 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
7087 return FunTmpl;
7088
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007089 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00007090 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
7091 return ClassTmpl;
7092
7093 return D;
7094}
7095
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00007096
7097enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
7098 StorageClass sc = SC_None;
7099 const Decl *D = getCursorDecl(C);
7100 if (D) {
7101 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
7102 sc = FD->getStorageClass();
7103 } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
7104 sc = VD->getStorageClass();
7105 } else {
7106 return CX_SC_Invalid;
7107 }
7108 } else {
7109 return CX_SC_Invalid;
7110 }
7111 switch (sc) {
7112 case SC_None:
7113 return CX_SC_None;
7114 case SC_Extern:
7115 return CX_SC_Extern;
7116 case SC_Static:
7117 return CX_SC_Static;
7118 case SC_PrivateExtern:
7119 return CX_SC_PrivateExtern;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00007120 case SC_Auto:
7121 return CX_SC_Auto;
7122 case SC_Register:
7123 return CX_SC_Register;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00007124 }
Kaelyn Takataab61e702014-10-15 18:03:26 +00007125 llvm_unreachable("Unhandled storage class!");
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00007126}
7127
Guy Benyei11169dd2012-12-18 14:30:41 +00007128CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
7129 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007130 if (const Decl *D = getCursorDecl(cursor)) {
7131 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00007132 if (!DC)
7133 return clang_getNullCursor();
7134
7135 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
7136 getCursorTU(cursor));
7137 }
7138 }
7139
7140 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007141 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00007142 return MakeCXCursor(D, getCursorTU(cursor));
7143 }
7144
7145 return clang_getNullCursor();
7146}
7147
7148CXCursor clang_getCursorLexicalParent(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->getLexicalDeclContext();
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 // FIXME: Note that we can't easily compute the lexical context of a
7161 // statement or expression, so we return nothing.
7162 return clang_getNullCursor();
7163}
7164
7165CXFile clang_getIncludedFile(CXCursor cursor) {
7166 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00007167 return nullptr;
7168
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007169 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00007170 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00007171}
7172
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00007173unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
7174 if (C.kind != CXCursor_ObjCPropertyDecl)
7175 return CXObjCPropertyAttr_noattr;
7176
7177 unsigned Result = CXObjCPropertyAttr_noattr;
7178 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
7179 ObjCPropertyDecl::PropertyAttributeKind Attr =
7180 PD->getPropertyAttributesAsWritten();
7181
7182#define SET_CXOBJCPROP_ATTR(A) \
7183 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
7184 Result |= CXObjCPropertyAttr_##A
7185 SET_CXOBJCPROP_ATTR(readonly);
7186 SET_CXOBJCPROP_ATTR(getter);
7187 SET_CXOBJCPROP_ATTR(assign);
7188 SET_CXOBJCPROP_ATTR(readwrite);
7189 SET_CXOBJCPROP_ATTR(retain);
7190 SET_CXOBJCPROP_ATTR(copy);
7191 SET_CXOBJCPROP_ATTR(nonatomic);
7192 SET_CXOBJCPROP_ATTR(setter);
7193 SET_CXOBJCPROP_ATTR(atomic);
7194 SET_CXOBJCPROP_ATTR(weak);
7195 SET_CXOBJCPROP_ATTR(strong);
7196 SET_CXOBJCPROP_ATTR(unsafe_unretained);
7197#undef SET_CXOBJCPROP_ATTR
7198
7199 return Result;
7200}
7201
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00007202unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
7203 if (!clang_isDeclaration(C.kind))
7204 return CXObjCDeclQualifier_None;
7205
7206 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
7207 const Decl *D = getCursorDecl(C);
7208 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
7209 QT = MD->getObjCDeclQualifier();
7210 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
7211 QT = PD->getObjCDeclQualifier();
7212 if (QT == Decl::OBJC_TQ_None)
7213 return CXObjCDeclQualifier_None;
7214
7215 unsigned Result = CXObjCDeclQualifier_None;
7216 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
7217 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
7218 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
7219 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
7220 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
7221 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
7222
7223 return Result;
7224}
7225
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00007226unsigned clang_Cursor_isObjCOptional(CXCursor C) {
7227 if (!clang_isDeclaration(C.kind))
7228 return 0;
7229
7230 const Decl *D = getCursorDecl(C);
7231 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
7232 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
7233 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
7234 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
7235
7236 return 0;
7237}
7238
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00007239unsigned clang_Cursor_isVariadic(CXCursor C) {
7240 if (!clang_isDeclaration(C.kind))
7241 return 0;
7242
7243 const Decl *D = getCursorDecl(C);
7244 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
7245 return FD->isVariadic();
7246 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
7247 return MD->isVariadic();
7248
7249 return 0;
7250}
7251
Guy Benyei11169dd2012-12-18 14:30:41 +00007252CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
7253 if (!clang_isDeclaration(C.kind))
7254 return clang_getNullRange();
7255
7256 const Decl *D = getCursorDecl(C);
7257 ASTContext &Context = getCursorContext(C);
7258 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
7259 if (!RC)
7260 return clang_getNullRange();
7261
7262 return cxloc::translateSourceRange(Context, RC->getSourceRange());
7263}
7264
7265CXString clang_Cursor_getRawCommentText(CXCursor C) {
7266 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00007267 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00007268
7269 const Decl *D = getCursorDecl(C);
7270 ASTContext &Context = getCursorContext(C);
7271 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
7272 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
7273 StringRef();
7274
7275 // Don't duplicate the string because RawText points directly into source
7276 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007277 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00007278}
7279
7280CXString clang_Cursor_getBriefCommentText(CXCursor C) {
7281 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00007282 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00007283
7284 const Decl *D = getCursorDecl(C);
7285 const ASTContext &Context = getCursorContext(C);
7286 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
7287
7288 if (RC) {
7289 StringRef BriefText = RC->getBriefText(Context);
7290
7291 // Don't duplicate the string because RawComment ensures that this memory
7292 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007293 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00007294 }
7295
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00007296 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00007297}
7298
Guy Benyei11169dd2012-12-18 14:30:41 +00007299CXModule clang_Cursor_getModule(CXCursor C) {
7300 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007301 if (const ImportDecl *ImportD =
7302 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00007303 return ImportD->getImportedModule();
7304 }
7305
Craig Topper69186e72014-06-08 08:38:04 +00007306 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007307}
7308
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00007309CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
7310 if (isNotUsableTU(TU)) {
7311 LOG_BAD_TU(TU);
7312 return nullptr;
7313 }
7314 if (!File)
7315 return nullptr;
7316 FileEntry *FE = static_cast<FileEntry *>(File);
7317
7318 ASTUnit &Unit = *cxtu::getASTUnit(TU);
7319 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
7320 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
7321
Richard Smithfeb54b62014-10-23 02:01:19 +00007322 return Header.getModule();
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00007323}
7324
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00007325CXFile clang_Module_getASTFile(CXModule CXMod) {
7326 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00007327 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00007328 Module *Mod = static_cast<Module*>(CXMod);
7329 return const_cast<FileEntry *>(Mod->getASTFile());
7330}
7331
Guy Benyei11169dd2012-12-18 14:30:41 +00007332CXModule clang_Module_getParent(CXModule CXMod) {
7333 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00007334 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007335 Module *Mod = static_cast<Module*>(CXMod);
7336 return Mod->Parent;
7337}
7338
7339CXString clang_Module_getName(CXModule CXMod) {
7340 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007341 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00007342 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007343 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00007344}
7345
7346CXString clang_Module_getFullName(CXModule CXMod) {
7347 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007348 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00007349 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007350 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00007351}
7352
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00007353int clang_Module_isSystem(CXModule CXMod) {
7354 if (!CXMod)
7355 return 0;
7356 Module *Mod = static_cast<Module*>(CXMod);
7357 return Mod->IsSystem;
7358}
7359
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007360unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
7361 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007362 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007363 LOG_BAD_TU(TU);
7364 return 0;
7365 }
7366 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00007367 return 0;
7368 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007369 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
7370 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
7371 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00007372}
7373
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007374CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
7375 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007376 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007377 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00007378 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007379 }
7380 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00007381 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007382 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007383 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00007384
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007385 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
7386 if (Index < TopHeaders.size())
7387 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00007388
Craig Topper69186e72014-06-08 08:38:04 +00007389 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007390}
7391
7392} // end: extern "C"
7393
7394//===----------------------------------------------------------------------===//
7395// C++ AST instrospection.
7396//===----------------------------------------------------------------------===//
7397
7398extern "C" {
Saleem Abdulrasool6ea75db2015-10-27 15:50:22 +00007399unsigned clang_CXXField_isMutable(CXCursor C) {
7400 if (!clang_isDeclaration(C.kind))
7401 return 0;
7402
7403 if (const auto D = cxcursor::getCursorDecl(C))
7404 if (const auto FD = dyn_cast_or_null<FieldDecl>(D))
7405 return FD->isMutable() ? 1 : 0;
7406 return 0;
7407}
7408
Dmitri Gribenko62770be2013-05-17 18:38:35 +00007409unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
7410 if (!clang_isDeclaration(C.kind))
7411 return 0;
7412
Dmitri Gribenko62770be2013-05-17 18:38:35 +00007413 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007414 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007415 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00007416 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
7417}
7418
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00007419unsigned clang_CXXMethod_isConst(CXCursor C) {
7420 if (!clang_isDeclaration(C.kind))
7421 return 0;
7422
7423 const Decl *D = cxcursor::getCursorDecl(C);
7424 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007425 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00007426 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
7427}
7428
Guy Benyei11169dd2012-12-18 14:30:41 +00007429unsigned clang_CXXMethod_isStatic(CXCursor C) {
7430 if (!clang_isDeclaration(C.kind))
7431 return 0;
7432
Dmitri Gribenkod15bb302013-01-23 17:25:27 +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;
Guy Benyei11169dd2012-12-18 14:30:41 +00007436 return (Method && Method->isStatic()) ? 1 : 0;
7437}
7438
7439unsigned clang_CXXMethod_isVirtual(CXCursor C) {
7440 if (!clang_isDeclaration(C.kind))
7441 return 0;
7442
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007443 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007444 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007445 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007446 return (Method && Method->isVirtual()) ? 1 : 0;
7447}
7448} // end: extern "C"
7449
7450//===----------------------------------------------------------------------===//
7451// Attribute introspection.
7452//===----------------------------------------------------------------------===//
7453
7454extern "C" {
7455CXType clang_getIBOutletCollectionType(CXCursor C) {
7456 if (C.kind != CXCursor_IBOutletCollectionAttr)
7457 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
7458
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00007459 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00007460 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
7461
7462 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
7463}
7464} // end: extern "C"
7465
7466//===----------------------------------------------------------------------===//
7467// Inspecting memory usage.
7468//===----------------------------------------------------------------------===//
7469
7470typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
7471
7472static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
7473 enum CXTUResourceUsageKind k,
7474 unsigned long amount) {
7475 CXTUResourceUsageEntry entry = { k, amount };
7476 entries.push_back(entry);
7477}
7478
7479extern "C" {
7480
7481const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
7482 const char *str = "";
7483 switch (kind) {
7484 case CXTUResourceUsage_AST:
7485 str = "ASTContext: expressions, declarations, and types";
7486 break;
7487 case CXTUResourceUsage_Identifiers:
7488 str = "ASTContext: identifiers";
7489 break;
7490 case CXTUResourceUsage_Selectors:
7491 str = "ASTContext: selectors";
7492 break;
7493 case CXTUResourceUsage_GlobalCompletionResults:
7494 str = "Code completion: cached global results";
7495 break;
7496 case CXTUResourceUsage_SourceManagerContentCache:
7497 str = "SourceManager: content cache allocator";
7498 break;
7499 case CXTUResourceUsage_AST_SideTables:
7500 str = "ASTContext: side tables";
7501 break;
7502 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
7503 str = "SourceManager: malloc'ed memory buffers";
7504 break;
7505 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
7506 str = "SourceManager: mmap'ed memory buffers";
7507 break;
7508 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
7509 str = "ExternalASTSource: malloc'ed memory buffers";
7510 break;
7511 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
7512 str = "ExternalASTSource: mmap'ed memory buffers";
7513 break;
7514 case CXTUResourceUsage_Preprocessor:
7515 str = "Preprocessor: malloc'ed memory";
7516 break;
7517 case CXTUResourceUsage_PreprocessingRecord:
7518 str = "Preprocessor: PreprocessingRecord";
7519 break;
7520 case CXTUResourceUsage_SourceManager_DataStructures:
7521 str = "SourceManager: data structures and tables";
7522 break;
7523 case CXTUResourceUsage_Preprocessor_HeaderSearch:
7524 str = "Preprocessor: header search tables";
7525 break;
7526 }
7527 return str;
7528}
7529
7530CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007531 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007532 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00007533 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00007534 return usage;
7535 }
7536
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007537 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00007538 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00007539 ASTContext &astContext = astUnit->getASTContext();
7540
7541 // How much memory is used by AST nodes and types?
7542 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
7543 (unsigned long) astContext.getASTAllocatedMemory());
7544
7545 // How much memory is used by identifiers?
7546 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
7547 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
7548
7549 // How much memory is used for selectors?
7550 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
7551 (unsigned long) astContext.Selectors.getTotalMemory());
7552
7553 // How much memory is used by ASTContext's side tables?
7554 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
7555 (unsigned long) astContext.getSideTableAllocatedMemory());
7556
7557 // How much memory is used for caching global code completion results?
7558 unsigned long completionBytes = 0;
7559 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00007560 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007561 completionBytes = completionAllocator->getTotalMemory();
7562 }
7563 createCXTUResourceUsageEntry(*entries,
7564 CXTUResourceUsage_GlobalCompletionResults,
7565 completionBytes);
7566
7567 // How much memory is being used by SourceManager's content cache?
7568 createCXTUResourceUsageEntry(*entries,
7569 CXTUResourceUsage_SourceManagerContentCache,
7570 (unsigned long) astContext.getSourceManager().getContentCacheSize());
7571
7572 // How much memory is being used by the MemoryBuffer's in SourceManager?
7573 const SourceManager::MemoryBufferSizes &srcBufs =
7574 astUnit->getSourceManager().getMemoryBufferSizes();
7575
7576 createCXTUResourceUsageEntry(*entries,
7577 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
7578 (unsigned long) srcBufs.malloc_bytes);
7579 createCXTUResourceUsageEntry(*entries,
7580 CXTUResourceUsage_SourceManager_Membuffer_MMap,
7581 (unsigned long) srcBufs.mmap_bytes);
7582 createCXTUResourceUsageEntry(*entries,
7583 CXTUResourceUsage_SourceManager_DataStructures,
7584 (unsigned long) astContext.getSourceManager()
7585 .getDataStructureSizes());
7586
7587 // How much memory is being used by the ExternalASTSource?
7588 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
7589 const ExternalASTSource::MemoryBufferSizes &sizes =
7590 esrc->getMemoryBufferSizes();
7591
7592 createCXTUResourceUsageEntry(*entries,
7593 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
7594 (unsigned long) sizes.malloc_bytes);
7595 createCXTUResourceUsageEntry(*entries,
7596 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
7597 (unsigned long) sizes.mmap_bytes);
7598 }
7599
7600 // How much memory is being used by the Preprocessor?
7601 Preprocessor &pp = astUnit->getPreprocessor();
7602 createCXTUResourceUsageEntry(*entries,
7603 CXTUResourceUsage_Preprocessor,
7604 pp.getTotalMemory());
7605
7606 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
7607 createCXTUResourceUsageEntry(*entries,
7608 CXTUResourceUsage_PreprocessingRecord,
7609 pRec->getTotalMemory());
7610 }
7611
7612 createCXTUResourceUsageEntry(*entries,
7613 CXTUResourceUsage_Preprocessor_HeaderSearch,
7614 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00007615
Guy Benyei11169dd2012-12-18 14:30:41 +00007616 CXTUResourceUsage usage = { (void*) entries.get(),
7617 (unsigned) entries->size(),
Alexander Kornienko6ee521c2015-01-23 15:36:10 +00007618 !entries->empty() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00007619 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00007620 return usage;
7621}
7622
7623void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
7624 if (usage.data)
7625 delete (MemUsageEntries*) usage.data;
7626}
7627
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007628CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
7629 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007630 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00007631 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007632
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007633 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007634 LOG_BAD_TU(TU);
7635 return skipped;
7636 }
7637
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007638 if (!file)
7639 return skipped;
7640
7641 ASTUnit *astUnit = cxtu::getASTUnit(TU);
7642 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
7643 if (!ppRec)
7644 return skipped;
7645
7646 ASTContext &Ctx = astUnit->getASTContext();
7647 SourceManager &sm = Ctx.getSourceManager();
7648 FileEntry *fileEntry = static_cast<FileEntry *>(file);
7649 FileID wantedFileID = sm.translateFile(fileEntry);
7650
7651 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
7652 std::vector<SourceRange> wantedRanges;
7653 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
7654 i != ei; ++i) {
7655 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
7656 wantedRanges.push_back(*i);
7657 }
7658
7659 skipped->count = wantedRanges.size();
7660 skipped->ranges = new CXSourceRange[skipped->count];
7661 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
7662 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
7663
7664 return skipped;
7665}
7666
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007667void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
7668 if (ranges) {
7669 delete[] ranges->ranges;
7670 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007671 }
7672}
7673
Guy Benyei11169dd2012-12-18 14:30:41 +00007674} // end extern "C"
7675
7676void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
7677 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
7678 for (unsigned I = 0; I != Usage.numEntries; ++I)
7679 fprintf(stderr, " %s: %lu\n",
7680 clang_getTUResourceUsageName(Usage.entries[I].kind),
7681 Usage.entries[I].amount);
7682
7683 clang_disposeCXTUResourceUsage(Usage);
7684}
7685
7686//===----------------------------------------------------------------------===//
7687// Misc. utility functions.
7688//===----------------------------------------------------------------------===//
7689
7690/// Default to using an 8 MB stack size on "safety" threads.
7691static unsigned SafetyStackThreadSize = 8 << 20;
7692
7693namespace clang {
7694
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007695bool RunSafely(llvm::CrashRecoveryContext &CRC, llvm::function_ref<void()> Fn,
Guy Benyei11169dd2012-12-18 14:30:41 +00007696 unsigned Size) {
7697 if (!Size)
7698 Size = GetSafetyThreadStackSize();
7699 if (Size)
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007700 return CRC.RunSafelyOnThread(Fn, Size);
7701 return CRC.RunSafely(Fn);
Guy Benyei11169dd2012-12-18 14:30:41 +00007702}
7703
7704unsigned GetSafetyThreadStackSize() {
7705 return SafetyStackThreadSize;
7706}
7707
7708void SetSafetyThreadStackSize(unsigned Value) {
7709 SafetyStackThreadSize = Value;
7710}
7711
Alexander Kornienkoab9db512015-06-22 23:07:51 +00007712}
Guy Benyei11169dd2012-12-18 14:30:41 +00007713
7714void clang::setThreadBackgroundPriority() {
7715 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
7716 return;
7717
Alp Toker1a86ad22014-07-06 06:24:00 +00007718#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00007719 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
7720#endif
7721}
7722
7723void cxindex::printDiagsToStderr(ASTUnit *Unit) {
7724 if (!Unit)
7725 return;
7726
7727 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
7728 DEnd = Unit->stored_diag_end();
7729 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00007730 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00007731 CXString Msg = clang_formatDiagnostic(&Diag,
7732 clang_defaultDiagnosticDisplayOptions());
7733 fprintf(stderr, "%s\n", clang_getCString(Msg));
7734 clang_disposeString(Msg);
7735 }
7736#ifdef LLVM_ON_WIN32
7737 // On Windows, force a flush, since there may be multiple copies of
7738 // stderr and stdout in the file system, all with different buffers
7739 // but writing to the same device.
7740 fflush(stderr);
7741#endif
7742}
7743
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007744MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
7745 SourceLocation MacroDefLoc,
7746 CXTranslationUnit TU){
7747 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007748 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007749 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007750 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007751
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007752 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007753 Preprocessor &PP = Unit->getPreprocessor();
Richard Smith20e883e2015-04-29 23:20:19 +00007754 MacroDirective *MD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007755 if (MD) {
7756 for (MacroDirective::DefInfo
7757 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
7758 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
7759 return Def.getMacroInfo();
7760 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007761 }
7762
Craig Topper69186e72014-06-08 08:38:04 +00007763 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007764}
7765
Richard Smith66a81862015-05-04 02:25:31 +00007766const MacroInfo *cxindex::getMacroInfo(const MacroDefinitionRecord *MacroDef,
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007767 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007768 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007769 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007770 const IdentifierInfo *II = MacroDef->getName();
7771 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00007772 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007773
7774 return getMacroInfo(*II, MacroDef->getLocation(), TU);
7775}
7776
Richard Smith66a81862015-05-04 02:25:31 +00007777MacroDefinitionRecord *
7778cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, const Token &Tok,
7779 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007780 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007781 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007782 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00007783 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007784
7785 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007786 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007787 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
7788 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007789 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007790
7791 // Check that the token is inside the definition and not its argument list.
7792 SourceManager &SM = Unit->getSourceManager();
7793 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00007794 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007795 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00007796 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007797
7798 Preprocessor &PP = Unit->getPreprocessor();
7799 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
7800 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00007801 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007802
Alp Toker2d57cea2014-05-17 04:53:25 +00007803 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007804 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007805 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007806
7807 // Check that the identifier is not one of the macro arguments.
7808 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00007809 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007810
Richard Smith20e883e2015-04-29 23:20:19 +00007811 MacroDirective *InnerMD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007812 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00007813 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007814
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007815 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007816}
7817
Richard Smith66a81862015-05-04 02:25:31 +00007818MacroDefinitionRecord *
7819cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, SourceLocation Loc,
7820 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007821 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007822 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007823
7824 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007825 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007826 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007827 Preprocessor &PP = Unit->getPreprocessor();
7828 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00007829 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007830 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7831 Token Tok;
7832 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00007833 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007834
7835 return checkForMacroInMacroDefinition(MI, Tok, TU);
7836}
7837
Guy Benyei11169dd2012-12-18 14:30:41 +00007838extern "C" {
7839
7840CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007841 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00007842}
7843
7844} // end: extern "C"
7845
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007846Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7847 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007848 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007849 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007850 if (Unit->isMainFileAST())
7851 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007852 return *this;
7853 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007854 } else {
7855 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007856 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007857 return *this;
7858}
7859
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007860Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7861 *this << FE->getName();
7862 return *this;
7863}
7864
7865Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7866 CXString cursorName = clang_getCursorDisplayName(cursor);
7867 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7868 clang_disposeString(cursorName);
7869 return *this;
7870}
7871
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007872Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7873 CXFile File;
7874 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007875 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007876 CXString FileName = clang_getFileName(File);
7877 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7878 clang_disposeString(FileName);
7879 return *this;
7880}
7881
7882Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7883 CXSourceLocation BLoc = clang_getRangeStart(range);
7884 CXSourceLocation ELoc = clang_getRangeEnd(range);
7885
7886 CXFile BFile;
7887 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007888 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007889
7890 CXFile EFile;
7891 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007892 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007893
7894 CXString BFileName = clang_getFileName(BFile);
7895 if (BFile == EFile) {
7896 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7897 BLine, BColumn, ELine, EColumn);
7898 } else {
7899 CXString EFileName = clang_getFileName(EFile);
7900 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7901 BLine, BColumn)
7902 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7903 ELine, EColumn);
7904 clang_disposeString(EFileName);
7905 }
7906 clang_disposeString(BFileName);
7907 return *this;
7908}
7909
7910Logger &cxindex::Logger::operator<<(CXString Str) {
7911 *this << clang_getCString(Str);
7912 return *this;
7913}
7914
7915Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7916 LogOS << Fmt;
7917 return *this;
7918}
7919
Chandler Carruth37ad2582014-06-27 15:14:39 +00007920static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7921
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007922cxindex::Logger::~Logger() {
Chandler Carruth37ad2582014-06-27 15:14:39 +00007923 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007924
7925 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7926
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007927 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007928 OS << "[libclang:" << Name << ':';
7929
Alp Toker1a86ad22014-07-06 06:24:00 +00007930#ifdef USE_DARWIN_THREADS
7931 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007932 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7933 OS << tid << ':';
7934#endif
7935
7936 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7937 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
Yaron Keren09fb7c62015-03-10 07:33:23 +00007938 OS << Msg << '\n';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007939
7940 if (Trace) {
Zachary Turner1fe2a8d2015-03-05 19:15:09 +00007941 llvm::sys::PrintStackTrace(OS);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007942 OS << "--------------------------------------------------\n";
7943 }
7944}