blob: 768cd6a5b2398cb3b3910ae74f70685d4784edbd [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 }
720
721 if (ShouldVisitBody && VisitCXXRecordDecl(D))
722 return true;
723
724 return false;
725}
726
727bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
728 ClassTemplatePartialSpecializationDecl *D) {
729 // FIXME: Visit the "outer" template parameter lists on the TagDecl
730 // before visiting these template parameters.
731 if (VisitTemplateParameters(D->getTemplateParameters()))
732 return true;
733
734 // Visit the partial specialization arguments.
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000735 const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
736 const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
737 for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
Guy Benyei11169dd2012-12-18 14:30:41 +0000738 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
739 return true;
740
741 return VisitCXXRecordDecl(D);
742}
743
744bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
745 // Visit the default argument.
746 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
747 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
748 if (Visit(DefArg->getTypeLoc()))
749 return true;
750
751 return false;
752}
753
754bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
755 if (Expr *Init = D->getInitExpr())
756 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
757 return false;
758}
759
760bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000761 unsigned NumParamList = DD->getNumTemplateParameterLists();
762 for (unsigned i = 0; i < NumParamList; i++) {
763 TemplateParameterList* Params = DD->getTemplateParameterList(i);
764 if (VisitTemplateParameters(Params))
765 return true;
766 }
767
Guy Benyei11169dd2012-12-18 14:30:41 +0000768 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
769 if (Visit(TSInfo->getTypeLoc()))
770 return true;
771
772 // Visit the nested-name-specifier, if present.
773 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
774 if (VisitNestedNameSpecifierLoc(QualifierLoc))
775 return true;
776
777 return false;
778}
779
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000780/// \brief Compare two base or member initializers based on their source order.
781static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
782 CXXCtorInitializer *const *Y) {
783 return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
784}
785
Guy Benyei11169dd2012-12-18 14:30:41 +0000786bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000787 unsigned NumParamList = ND->getNumTemplateParameterLists();
788 for (unsigned i = 0; i < NumParamList; i++) {
789 TemplateParameterList* Params = ND->getTemplateParameterList(i);
790 if (VisitTemplateParameters(Params))
791 return true;
792 }
793
Guy Benyei11169dd2012-12-18 14:30:41 +0000794 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
795 // Visit the function declaration's syntactic components in the order
796 // written. This requires a bit of work.
797 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
David Blaikie6adc78e2013-02-18 22:06:02 +0000798 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Guy Benyei11169dd2012-12-18 14:30:41 +0000799
800 // If we have a function declared directly (without the use of a typedef),
801 // visit just the return type. Otherwise, just visit the function's type
802 // now.
Alp Toker42a16a62014-01-25 23:51:36 +0000803 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getReturnLoc())) ||
Guy Benyei11169dd2012-12-18 14:30:41 +0000804 (!FTL && Visit(TL)))
805 return true;
806
807 // Visit the nested-name-specifier, if present.
808 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
809 if (VisitNestedNameSpecifierLoc(QualifierLoc))
810 return true;
811
812 // Visit the declaration name.
Argyrios Kyrtzidis4a4d2b42014-02-09 08:13:47 +0000813 if (!isa<CXXDestructorDecl>(ND))
814 if (VisitDeclarationNameInfo(ND->getNameInfo()))
815 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +0000816
817 // FIXME: Visit explicitly-specified template arguments!
818
819 // Visit the function parameters, if we have a function type.
David Blaikie6adc78e2013-02-18 22:06:02 +0000820 if (FTL && VisitFunctionTypeLoc(FTL, true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000821 return true;
822
Bill Wendling44426052012-12-20 19:22:21 +0000823 // FIXME: Attributes?
Guy Benyei11169dd2012-12-18 14:30:41 +0000824 }
825
826 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
827 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
828 // Find the initializers that were written in the source.
829 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
Aaron Ballman0ad78302014-03-13 17:34:31 +0000830 for (auto *I : Constructor->inits()) {
831 if (!I->isWritten())
Guy Benyei11169dd2012-12-18 14:30:41 +0000832 continue;
833
Aaron Ballman0ad78302014-03-13 17:34:31 +0000834 WrittenInits.push_back(I);
Guy Benyei11169dd2012-12-18 14:30:41 +0000835 }
836
837 // Sort the initializers in source order
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000838 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
839 &CompareCXXCtorInitializers);
840
Guy Benyei11169dd2012-12-18 14:30:41 +0000841 // Visit the initializers in source order
842 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
843 CXXCtorInitializer *Init = WrittenInits[I];
844 if (Init->isAnyMemberInitializer()) {
845 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
846 Init->getMemberLocation(), TU)))
847 return true;
848 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
849 if (Visit(TInfo->getTypeLoc()))
850 return true;
851 }
852
853 // Visit the initializer value.
854 if (Expr *Initializer = Init->getInit())
855 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
856 return true;
857 }
858 }
859
860 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
861 return true;
862 }
863
864 return false;
865}
866
867bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
868 if (VisitDeclaratorDecl(D))
869 return true;
870
871 if (Expr *BitWidth = D->getBitWidth())
872 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
873
874 return false;
875}
876
877bool CursorVisitor::VisitVarDecl(VarDecl *D) {
878 if (VisitDeclaratorDecl(D))
879 return true;
880
881 if (Expr *Init = D->getInit())
882 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
883
884 return false;
885}
886
887bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
888 if (VisitDeclaratorDecl(D))
889 return true;
890
891 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
892 if (Expr *DefArg = D->getDefaultArgument())
893 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
894
895 return false;
896}
897
898bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
899 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
900 // before visiting these template parameters.
901 if (VisitTemplateParameters(D->getTemplateParameters()))
902 return true;
903
904 return VisitFunctionDecl(D->getTemplatedDecl());
905}
906
907bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
908 // FIXME: Visit the "outer" template parameter lists on the TagDecl
909 // before visiting these template parameters.
910 if (VisitTemplateParameters(D->getTemplateParameters()))
911 return true;
912
913 return VisitCXXRecordDecl(D->getTemplatedDecl());
914}
915
916bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
917 if (VisitTemplateParameters(D->getTemplateParameters()))
918 return true;
919
920 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
921 VisitTemplateArgumentLoc(D->getDefaultArgument()))
922 return true;
923
924 return false;
925}
926
Douglas Gregor9bda6cf2015-07-07 03:58:14 +0000927bool CursorVisitor::VisitObjCTypeParamDecl(ObjCTypeParamDecl *D) {
928 // Visit the bound, if it's explicit.
929 if (D->hasExplicitBound()) {
930 if (auto TInfo = D->getTypeSourceInfo()) {
931 if (Visit(TInfo->getTypeLoc()))
932 return true;
933 }
934 }
935
936 return false;
937}
938
Guy Benyei11169dd2012-12-18 14:30:41 +0000939bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Alp Toker314cc812014-01-25 16:55:45 +0000940 if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
Guy Benyei11169dd2012-12-18 14:30:41 +0000941 if (Visit(TSInfo->getTypeLoc()))
942 return true;
943
Aaron Ballman43b68be2014-03-07 17:50:17 +0000944 for (const auto *P : ND->params()) {
945 if (Visit(MakeCXCursor(P, TU, RegionOfInterest)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000946 return true;
947 }
948
949 if (ND->isThisDeclarationADefinition() &&
950 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
951 return true;
952
953 return false;
954}
955
956template <typename DeclIt>
957static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
958 SourceManager &SM, SourceLocation EndLoc,
959 SmallVectorImpl<Decl *> &Decls) {
960 DeclIt next = *DI_current;
961 while (++next != DE_current) {
962 Decl *D_next = *next;
963 if (!D_next)
964 break;
965 SourceLocation L = D_next->getLocStart();
966 if (!L.isValid())
967 break;
968 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
969 *DI_current = next;
970 Decls.push_back(D_next);
971 continue;
972 }
973 break;
974 }
975}
976
Guy Benyei11169dd2012-12-18 14:30:41 +0000977bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
978 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
979 // an @implementation can lexically contain Decls that are not properly
980 // nested in the AST. When we identify such cases, we need to retrofit
981 // this nesting here.
982 if (!DI_current && !FileDI_current)
983 return VisitDeclContext(D);
984
985 // Scan the Decls that immediately come after the container
986 // in the current DeclContext. If any fall within the
987 // container's lexical region, stash them into a vector
988 // for later processing.
989 SmallVector<Decl *, 24> DeclsInContainer;
990 SourceLocation EndLoc = D->getSourceRange().getEnd();
991 SourceManager &SM = AU->getSourceManager();
992 if (EndLoc.isValid()) {
993 if (DI_current) {
994 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
995 DeclsInContainer);
996 } else {
997 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
998 DeclsInContainer);
999 }
1000 }
1001
1002 // The common case.
1003 if (DeclsInContainer.empty())
1004 return VisitDeclContext(D);
1005
1006 // Get all the Decls in the DeclContext, and sort them with the
1007 // additional ones we've collected. Then visit them.
Aaron Ballman629afae2014-03-07 19:56:05 +00001008 for (auto *SubDecl : D->decls()) {
1009 if (!SubDecl || SubDecl->getLexicalDeclContext() != D ||
1010 SubDecl->getLocStart().isInvalid())
Guy Benyei11169dd2012-12-18 14:30:41 +00001011 continue;
Aaron Ballman629afae2014-03-07 19:56:05 +00001012 DeclsInContainer.push_back(SubDecl);
Guy Benyei11169dd2012-12-18 14:30:41 +00001013 }
1014
1015 // Now sort the Decls so that they appear in lexical order.
1016 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
Benjamin Kramerbbdd7642014-03-01 14:48:57 +00001017 [&SM](Decl *A, Decl *B) {
1018 SourceLocation L_A = A->getLocStart();
1019 SourceLocation L_B = B->getLocStart();
1020 assert(L_A.isValid() && L_B.isValid());
1021 return SM.isBeforeInTranslationUnit(L_A, L_B);
1022 });
Guy Benyei11169dd2012-12-18 14:30:41 +00001023
1024 // Now visit the decls.
1025 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
1026 E = DeclsInContainer.end(); I != E; ++I) {
1027 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek03325582013-02-21 01:29:01 +00001028 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00001029 if (!V.hasValue())
1030 continue;
1031 if (!V.getValue())
1032 return false;
1033 if (Visit(Cursor, true))
1034 return true;
1035 }
1036 return false;
1037}
1038
1039bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1040 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1041 TU)))
1042 return true;
1043
Douglas Gregore9d95f12015-07-07 03:57:35 +00001044 if (VisitObjCTypeParamList(ND->getTypeParamList()))
1045 return true;
1046
Guy Benyei11169dd2012-12-18 14:30:41 +00001047 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1048 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1049 E = ND->protocol_end(); I != E; ++I, ++PL)
1050 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1051 return true;
1052
1053 return VisitObjCContainerDecl(ND);
1054}
1055
1056bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1057 if (!PID->isThisDeclarationADefinition())
1058 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1059
1060 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1061 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1062 E = PID->protocol_end(); I != E; ++I, ++PL)
1063 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1064 return true;
1065
1066 return VisitObjCContainerDecl(PID);
1067}
1068
1069bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1070 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1071 return true;
1072
1073 // FIXME: This implements a workaround with @property declarations also being
1074 // installed in the DeclContext for the @interface. Eventually this code
1075 // should be removed.
1076 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1077 if (!CDecl || !CDecl->IsClassExtension())
1078 return false;
1079
1080 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1081 if (!ID)
1082 return false;
1083
1084 IdentifierInfo *PropertyId = PD->getIdentifier();
1085 ObjCPropertyDecl *prevDecl =
1086 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1087
1088 if (!prevDecl)
1089 return false;
1090
1091 // Visit synthesized methods since they will be skipped when visiting
1092 // the @interface.
1093 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1094 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1095 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1096 return true;
1097
1098 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1099 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1100 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1101 return true;
1102
1103 return false;
1104}
1105
Douglas Gregore9d95f12015-07-07 03:57:35 +00001106bool CursorVisitor::VisitObjCTypeParamList(ObjCTypeParamList *typeParamList) {
1107 if (!typeParamList)
1108 return false;
1109
1110 for (auto *typeParam : *typeParamList) {
1111 // Visit the type parameter.
1112 if (Visit(MakeCXCursor(typeParam, TU, RegionOfInterest)))
1113 return true;
Douglas Gregore9d95f12015-07-07 03:57:35 +00001114 }
1115
1116 return false;
1117}
1118
Guy Benyei11169dd2012-12-18 14:30:41 +00001119bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1120 if (!D->isThisDeclarationADefinition()) {
1121 // Forward declaration is treated like a reference.
1122 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1123 }
1124
Douglas Gregore9d95f12015-07-07 03:57:35 +00001125 // Objective-C type parameters.
1126 if (VisitObjCTypeParamList(D->getTypeParamListAsWritten()))
1127 return true;
1128
Guy Benyei11169dd2012-12-18 14:30:41 +00001129 // Issue callbacks for super class.
1130 if (D->getSuperClass() &&
1131 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1132 D->getSuperClassLoc(),
1133 TU)))
1134 return true;
1135
Douglas Gregore9d95f12015-07-07 03:57:35 +00001136 if (TypeSourceInfo *SuperClassTInfo = D->getSuperClassTInfo())
1137 if (Visit(SuperClassTInfo->getTypeLoc()))
1138 return true;
1139
Guy Benyei11169dd2012-12-18 14:30:41 +00001140 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1141 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1142 E = D->protocol_end(); I != E; ++I, ++PL)
1143 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1144 return true;
1145
1146 return VisitObjCContainerDecl(D);
1147}
1148
1149bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1150 return VisitObjCContainerDecl(D);
1151}
1152
1153bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1154 // 'ID' could be null when dealing with invalid code.
1155 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1156 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1157 return true;
1158
1159 return VisitObjCImplDecl(D);
1160}
1161
1162bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1163#if 0
1164 // Issue callbacks for super class.
1165 // FIXME: No source location information!
1166 if (D->getSuperClass() &&
1167 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1168 D->getSuperClassLoc(),
1169 TU)))
1170 return true;
1171#endif
1172
1173 return VisitObjCImplDecl(D);
1174}
1175
1176bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1177 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1178 if (PD->isIvarNameSpecified())
1179 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1180
1181 return false;
1182}
1183
1184bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1185 return VisitDeclContext(D);
1186}
1187
1188bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1189 // Visit nested-name-specifier.
1190 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1191 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1192 return true;
1193
1194 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1195 D->getTargetNameLoc(), TU));
1196}
1197
1198bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1199 // Visit nested-name-specifier.
1200 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1201 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1202 return true;
1203 }
1204
1205 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1206 return true;
1207
1208 return VisitDeclarationNameInfo(D->getNameInfo());
1209}
1210
1211bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1212 // Visit nested-name-specifier.
1213 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1214 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1215 return true;
1216
1217 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1218 D->getIdentLocation(), TU));
1219}
1220
1221bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1222 // Visit nested-name-specifier.
1223 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1224 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1225 return true;
1226 }
1227
1228 return VisitDeclarationNameInfo(D->getNameInfo());
1229}
1230
1231bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1232 UnresolvedUsingTypenameDecl *D) {
1233 // Visit nested-name-specifier.
1234 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1235 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1236 return true;
1237
1238 return false;
1239}
1240
1241bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1242 switch (Name.getName().getNameKind()) {
1243 case clang::DeclarationName::Identifier:
1244 case clang::DeclarationName::CXXLiteralOperatorName:
1245 case clang::DeclarationName::CXXOperatorName:
1246 case clang::DeclarationName::CXXUsingDirective:
1247 return false;
1248
1249 case clang::DeclarationName::CXXConstructorName:
1250 case clang::DeclarationName::CXXDestructorName:
1251 case clang::DeclarationName::CXXConversionFunctionName:
1252 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1253 return Visit(TSInfo->getTypeLoc());
1254 return false;
1255
1256 case clang::DeclarationName::ObjCZeroArgSelector:
1257 case clang::DeclarationName::ObjCOneArgSelector:
1258 case clang::DeclarationName::ObjCMultiArgSelector:
1259 // FIXME: Per-identifier location info?
1260 return false;
1261 }
1262
1263 llvm_unreachable("Invalid DeclarationName::Kind!");
1264}
1265
1266bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1267 SourceRange Range) {
1268 // FIXME: This whole routine is a hack to work around the lack of proper
1269 // source information in nested-name-specifiers (PR5791). Since we do have
1270 // a beginning source location, we can visit the first component of the
1271 // nested-name-specifier, if it's a single-token component.
1272 if (!NNS)
1273 return false;
1274
1275 // Get the first component in the nested-name-specifier.
1276 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1277 NNS = Prefix;
1278
1279 switch (NNS->getKind()) {
1280 case NestedNameSpecifier::Namespace:
1281 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1282 TU));
1283
1284 case NestedNameSpecifier::NamespaceAlias:
1285 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1286 Range.getBegin(), TU));
1287
1288 case NestedNameSpecifier::TypeSpec: {
1289 // If the type has a form where we know that the beginning of the source
1290 // range matches up with a reference cursor. Visit the appropriate reference
1291 // cursor.
1292 const Type *T = NNS->getAsType();
1293 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1294 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1295 if (const TagType *Tag = dyn_cast<TagType>(T))
1296 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1297 if (const TemplateSpecializationType *TST
1298 = dyn_cast<TemplateSpecializationType>(T))
1299 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1300 break;
1301 }
1302
1303 case NestedNameSpecifier::TypeSpecWithTemplate:
1304 case NestedNameSpecifier::Global:
1305 case NestedNameSpecifier::Identifier:
Nikola Smiljanic67860242014-09-26 00:28:20 +00001306 case NestedNameSpecifier::Super:
Guy Benyei11169dd2012-12-18 14:30:41 +00001307 break;
1308 }
1309
1310 return false;
1311}
1312
1313bool
1314CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1315 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1316 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1317 Qualifiers.push_back(Qualifier);
1318
1319 while (!Qualifiers.empty()) {
1320 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1321 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1322 switch (NNS->getKind()) {
1323 case NestedNameSpecifier::Namespace:
1324 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1325 Q.getLocalBeginLoc(),
1326 TU)))
1327 return true;
1328
1329 break;
1330
1331 case NestedNameSpecifier::NamespaceAlias:
1332 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1333 Q.getLocalBeginLoc(),
1334 TU)))
1335 return true;
1336
1337 break;
1338
1339 case NestedNameSpecifier::TypeSpec:
1340 case NestedNameSpecifier::TypeSpecWithTemplate:
1341 if (Visit(Q.getTypeLoc()))
1342 return true;
1343
1344 break;
1345
1346 case NestedNameSpecifier::Global:
1347 case NestedNameSpecifier::Identifier:
Nikola Smiljanic67860242014-09-26 00:28:20 +00001348 case NestedNameSpecifier::Super:
Guy Benyei11169dd2012-12-18 14:30:41 +00001349 break;
1350 }
1351 }
1352
1353 return false;
1354}
1355
1356bool CursorVisitor::VisitTemplateParameters(
1357 const TemplateParameterList *Params) {
1358 if (!Params)
1359 return false;
1360
1361 for (TemplateParameterList::const_iterator P = Params->begin(),
1362 PEnd = Params->end();
1363 P != PEnd; ++P) {
1364 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1365 return true;
1366 }
1367
1368 return false;
1369}
1370
1371bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1372 switch (Name.getKind()) {
1373 case TemplateName::Template:
1374 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1375
1376 case TemplateName::OverloadedTemplate:
1377 // Visit the overloaded template set.
1378 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1379 return true;
1380
1381 return false;
1382
1383 case TemplateName::DependentTemplate:
1384 // FIXME: Visit nested-name-specifier.
1385 return false;
1386
1387 case TemplateName::QualifiedTemplate:
1388 // FIXME: Visit nested-name-specifier.
1389 return Visit(MakeCursorTemplateRef(
1390 Name.getAsQualifiedTemplateName()->getDecl(),
1391 Loc, TU));
1392
1393 case TemplateName::SubstTemplateTemplateParm:
1394 return Visit(MakeCursorTemplateRef(
1395 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1396 Loc, TU));
1397
1398 case TemplateName::SubstTemplateTemplateParmPack:
1399 return Visit(MakeCursorTemplateRef(
1400 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1401 Loc, TU));
1402 }
1403
1404 llvm_unreachable("Invalid TemplateName::Kind!");
1405}
1406
1407bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1408 switch (TAL.getArgument().getKind()) {
1409 case TemplateArgument::Null:
1410 case TemplateArgument::Integral:
1411 case TemplateArgument::Pack:
1412 return false;
1413
1414 case TemplateArgument::Type:
1415 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1416 return Visit(TSInfo->getTypeLoc());
1417 return false;
1418
1419 case TemplateArgument::Declaration:
1420 if (Expr *E = TAL.getSourceDeclExpression())
1421 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1422 return false;
1423
1424 case TemplateArgument::NullPtr:
1425 if (Expr *E = TAL.getSourceNullPtrExpression())
1426 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1427 return false;
1428
1429 case TemplateArgument::Expression:
1430 if (Expr *E = TAL.getSourceExpression())
1431 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1432 return false;
1433
1434 case TemplateArgument::Template:
1435 case TemplateArgument::TemplateExpansion:
1436 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1437 return true;
1438
1439 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1440 TAL.getTemplateNameLoc());
1441 }
1442
1443 llvm_unreachable("Invalid TemplateArgument::Kind!");
1444}
1445
1446bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1447 return VisitDeclContext(D);
1448}
1449
1450bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1451 return Visit(TL.getUnqualifiedLoc());
1452}
1453
1454bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1455 ASTContext &Context = AU->getASTContext();
1456
1457 // Some builtin types (such as Objective-C's "id", "sel", and
1458 // "Class") have associated declarations. Create cursors for those.
1459 QualType VisitType;
1460 switch (TL.getTypePtr()->getKind()) {
1461
1462 case BuiltinType::Void:
1463 case BuiltinType::NullPtr:
1464 case BuiltinType::Dependent:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001465 case BuiltinType::OCLImage1d:
1466 case BuiltinType::OCLImage1dArray:
1467 case BuiltinType::OCLImage1dBuffer:
1468 case BuiltinType::OCLImage2d:
1469 case BuiltinType::OCLImage2dArray:
Alexey Bader9c8453f2015-09-15 11:18:52 +00001470 case BuiltinType::OCLImage2dDepth:
1471 case BuiltinType::OCLImage2dArrayDepth:
1472 case BuiltinType::OCLImage2dMSAA:
1473 case BuiltinType::OCLImage2dArrayMSAA:
1474 case BuiltinType::OCLImage2dMSAADepth:
1475 case BuiltinType::OCLImage2dArrayMSAADepth:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001476 case BuiltinType::OCLImage3d:
NAKAMURA Takumi288c42e2013-02-07 12:47:42 +00001477 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +00001478 case BuiltinType::OCLEvent:
Alexey Bader9c8453f2015-09-15 11:18:52 +00001479 case BuiltinType::OCLClkEvent:
1480 case BuiltinType::OCLQueue:
1481 case BuiltinType::OCLNDRange:
1482 case BuiltinType::OCLReserveID:
Guy Benyei11169dd2012-12-18 14:30:41 +00001483#define BUILTIN_TYPE(Id, SingletonId)
1484#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1485#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1486#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1487#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1488#include "clang/AST/BuiltinTypes.def"
1489 break;
1490
1491 case BuiltinType::ObjCId:
1492 VisitType = Context.getObjCIdType();
1493 break;
1494
1495 case BuiltinType::ObjCClass:
1496 VisitType = Context.getObjCClassType();
1497 break;
1498
1499 case BuiltinType::ObjCSel:
1500 VisitType = Context.getObjCSelType();
1501 break;
1502 }
1503
1504 if (!VisitType.isNull()) {
1505 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1506 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1507 TU));
1508 }
1509
1510 return false;
1511}
1512
1513bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1514 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1515}
1516
1517bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1518 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1519}
1520
1521bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1522 if (TL.isDefinition())
1523 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1524
1525 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1526}
1527
1528bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1529 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1530}
1531
1532bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
Hans Wennborg59dbe862015-09-29 20:56:43 +00001533 return Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +00001534}
1535
1536bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1537 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1538 return true;
1539
Douglas Gregore9d95f12015-07-07 03:57:35 +00001540 for (unsigned I = 0, N = TL.getNumTypeArgs(); I != N; ++I) {
1541 if (Visit(TL.getTypeArgTInfo(I)->getTypeLoc()))
1542 return true;
1543 }
1544
Guy Benyei11169dd2012-12-18 14:30:41 +00001545 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1546 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1547 TU)))
1548 return true;
1549 }
1550
1551 return false;
1552}
1553
1554bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1555 return Visit(TL.getPointeeLoc());
1556}
1557
1558bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1559 return Visit(TL.getInnerLoc());
1560}
1561
1562bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1563 return Visit(TL.getPointeeLoc());
1564}
1565
1566bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1567 return Visit(TL.getPointeeLoc());
1568}
1569
1570bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1571 return Visit(TL.getPointeeLoc());
1572}
1573
1574bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1575 return Visit(TL.getPointeeLoc());
1576}
1577
1578bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1579 return Visit(TL.getPointeeLoc());
1580}
1581
1582bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1583 return Visit(TL.getModifiedLoc());
1584}
1585
1586bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1587 bool SkipResultType) {
Alp Toker42a16a62014-01-25 23:51:36 +00001588 if (!SkipResultType && Visit(TL.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001589 return true;
1590
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00001591 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1592 if (Decl *D = TL.getParam(I))
Guy Benyei11169dd2012-12-18 14:30:41 +00001593 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1594 return true;
1595
1596 return false;
1597}
1598
1599bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1600 if (Visit(TL.getElementLoc()))
1601 return true;
1602
1603 if (Expr *Size = TL.getSizeExpr())
1604 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1605
1606 return false;
1607}
1608
Reid Kleckner8a365022013-06-24 17:51:48 +00001609bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1610 return Visit(TL.getOriginalLoc());
1611}
1612
Reid Kleckner0503a872013-12-05 01:23:43 +00001613bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1614 return Visit(TL.getOriginalLoc());
1615}
1616
Guy Benyei11169dd2012-12-18 14:30:41 +00001617bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1618 TemplateSpecializationTypeLoc TL) {
1619 // Visit the template name.
1620 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1621 TL.getTemplateNameLoc()))
1622 return true;
1623
1624 // Visit the template arguments.
1625 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1626 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1627 return true;
1628
1629 return false;
1630}
1631
1632bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1633 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1634}
1635
1636bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1637 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1638 return Visit(TSInfo->getTypeLoc());
1639
1640 return false;
1641}
1642
1643bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1644 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1645 return Visit(TSInfo->getTypeLoc());
1646
1647 return false;
1648}
1649
1650bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
Hans Wennborg59dbe862015-09-29 20:56:43 +00001651 return VisitNestedNameSpecifierLoc(TL.getQualifierLoc());
Guy Benyei11169dd2012-12-18 14:30:41 +00001652}
1653
1654bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1655 DependentTemplateSpecializationTypeLoc TL) {
1656 // Visit the nested-name-specifier, if there is one.
1657 if (TL.getQualifierLoc() &&
1658 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1659 return true;
1660
1661 // Visit the template arguments.
1662 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1663 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1664 return true;
1665
1666 return false;
1667}
1668
1669bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1670 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1671 return true;
1672
1673 return Visit(TL.getNamedTypeLoc());
1674}
1675
1676bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1677 return Visit(TL.getPatternLoc());
1678}
1679
1680bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1681 if (Expr *E = TL.getUnderlyingExpr())
1682 return Visit(MakeCXCursor(E, StmtParent, TU));
1683
1684 return false;
1685}
1686
1687bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1688 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1689}
1690
1691bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1692 return Visit(TL.getValueLoc());
1693}
1694
1695#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1696bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1697 return Visit##PARENT##Loc(TL); \
1698}
1699
1700DEFAULT_TYPELOC_IMPL(Complex, Type)
1701DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1702DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1703DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1704DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1705DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1706DEFAULT_TYPELOC_IMPL(Vector, Type)
1707DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1708DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1709DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1710DEFAULT_TYPELOC_IMPL(Record, TagType)
1711DEFAULT_TYPELOC_IMPL(Enum, TagType)
1712DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1713DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1714DEFAULT_TYPELOC_IMPL(Auto, Type)
1715
1716bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1717 // Visit the nested-name-specifier, if present.
1718 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1719 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1720 return true;
1721
1722 if (D->isCompleteDefinition()) {
Aaron Ballman574705e2014-03-13 15:41:46 +00001723 for (const auto &I : D->bases()) {
1724 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001725 return true;
1726 }
1727 }
1728
1729 return VisitTagDecl(D);
1730}
1731
1732bool CursorVisitor::VisitAttributes(Decl *D) {
Aaron Ballmanb97112e2014-03-08 22:19:01 +00001733 for (const auto *I : D->attrs())
1734 if (Visit(MakeCXCursor(I, D, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001735 return true;
1736
1737 return false;
1738}
1739
1740//===----------------------------------------------------------------------===//
1741// Data-recursive visitor methods.
1742//===----------------------------------------------------------------------===//
1743
1744namespace {
1745#define DEF_JOB(NAME, DATA, KIND)\
1746class NAME : public VisitorJob {\
1747public:\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001748 NAME(const DATA *d, CXCursor parent) : \
1749 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei11169dd2012-12-18 14:30:41 +00001750 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001751 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei11169dd2012-12-18 14:30:41 +00001752};
1753
1754DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1755DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1756DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1757DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1758DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1759 ExplicitTemplateArgsVisitKind)
1760DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1761DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1762DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1763#undef DEF_JOB
1764
1765class DeclVisit : public VisitorJob {
1766public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001767 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei11169dd2012-12-18 14:30:41 +00001768 VisitorJob(parent, VisitorJob::DeclVisitKind,
Craig Topper69186e72014-06-08 08:38:04 +00001769 D, isFirst ? (void*) 1 : (void*) nullptr) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001770 static bool classof(const VisitorJob *VJ) {
1771 return VJ->getKind() == DeclVisitKind;
1772 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001773 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Dmitri Gribenkoe5423a72015-03-23 19:23:50 +00001774 bool isFirst() const { return data[1] != nullptr; }
Guy Benyei11169dd2012-12-18 14:30:41 +00001775};
1776class TypeLocVisit : public VisitorJob {
1777public:
1778 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1779 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1780 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1781
1782 static bool classof(const VisitorJob *VJ) {
1783 return VJ->getKind() == TypeLocVisitKind;
1784 }
1785
1786 TypeLoc get() const {
1787 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001788 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001789 }
1790};
1791
1792class LabelRefVisit : public VisitorJob {
1793public:
1794 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1795 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1796 labelLoc.getPtrEncoding()) {}
1797
1798 static bool classof(const VisitorJob *VJ) {
1799 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1800 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001801 const LabelDecl *get() const {
1802 return static_cast<const LabelDecl *>(data[0]);
1803 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001804 SourceLocation getLoc() const {
1805 return SourceLocation::getFromPtrEncoding(data[1]); }
1806};
1807
1808class NestedNameSpecifierLocVisit : public VisitorJob {
1809public:
1810 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1811 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1812 Qualifier.getNestedNameSpecifier(),
1813 Qualifier.getOpaqueData()) { }
1814
1815 static bool classof(const VisitorJob *VJ) {
1816 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1817 }
1818
1819 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001820 return NestedNameSpecifierLoc(
1821 const_cast<NestedNameSpecifier *>(
1822 static_cast<const NestedNameSpecifier *>(data[0])),
1823 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001824 }
1825};
1826
1827class DeclarationNameInfoVisit : public VisitorJob {
1828public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001829 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001830 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001831 static bool classof(const VisitorJob *VJ) {
1832 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1833 }
1834 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001835 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001836 switch (S->getStmtClass()) {
1837 default:
1838 llvm_unreachable("Unhandled Stmt");
1839 case clang::Stmt::MSDependentExistsStmtClass:
1840 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1841 case Stmt::CXXDependentScopeMemberExprClass:
1842 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1843 case Stmt::DependentScopeDeclRefExprClass:
1844 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001845 case Stmt::OMPCriticalDirectiveClass:
1846 return cast<OMPCriticalDirective>(S)->getDirectiveName();
Guy Benyei11169dd2012-12-18 14:30:41 +00001847 }
1848 }
1849};
1850class MemberRefVisit : public VisitorJob {
1851public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001852 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei11169dd2012-12-18 14:30:41 +00001853 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1854 L.getPtrEncoding()) {}
1855 static bool classof(const VisitorJob *VJ) {
1856 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1857 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001858 const FieldDecl *get() const {
1859 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001860 }
1861 SourceLocation getLoc() const {
1862 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1863 }
1864};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001865class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001866 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001867 VisitorWorkList &WL;
1868 CXCursor Parent;
1869public:
1870 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1871 : WL(wl), Parent(parent) {}
1872
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001873 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1874 void VisitBlockExpr(const BlockExpr *B);
1875 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1876 void VisitCompoundStmt(const CompoundStmt *S);
1877 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1878 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1879 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1880 void VisitCXXNewExpr(const CXXNewExpr *E);
1881 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1882 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1883 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1884 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1885 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1886 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1887 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1888 void VisitCXXCatchStmt(const CXXCatchStmt *S);
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00001889 void VisitCXXForRangeStmt(const CXXForRangeStmt *S);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001890 void VisitDeclRefExpr(const DeclRefExpr *D);
1891 void VisitDeclStmt(const DeclStmt *S);
1892 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1893 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1894 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1895 void VisitForStmt(const ForStmt *FS);
1896 void VisitGotoStmt(const GotoStmt *GS);
1897 void VisitIfStmt(const IfStmt *If);
1898 void VisitInitListExpr(const InitListExpr *IE);
1899 void VisitMemberExpr(const MemberExpr *M);
1900 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1901 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1902 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1903 void VisitOverloadExpr(const OverloadExpr *E);
1904 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1905 void VisitStmt(const Stmt *S);
1906 void VisitSwitchStmt(const SwitchStmt *S);
1907 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001908 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1909 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1910 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1911 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1912 void VisitVAArgExpr(const VAArgExpr *E);
1913 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1914 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1915 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1916 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001917 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
Alexander Musman3aaab662014-08-19 11:27:13 +00001918 void VisitOMPLoopDirective(const OMPLoopDirective *D);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001919 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00001920 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00001921 void VisitOMPForDirective(const OMPForDirective *D);
Alexander Musmanf82886e2014-09-18 05:12:34 +00001922 void VisitOMPForSimdDirective(const OMPForSimdDirective *D);
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00001923 void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
Alexey Bataev1e0498a2014-06-26 08:21:58 +00001924 void VisitOMPSectionDirective(const OMPSectionDirective *D);
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00001925 void VisitOMPSingleDirective(const OMPSingleDirective *D);
Alexander Musman80c22892014-07-17 08:54:58 +00001926 void VisitOMPMasterDirective(const OMPMasterDirective *D);
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001927 void VisitOMPCriticalDirective(const OMPCriticalDirective *D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00001928 void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
Alexander Musmane4e893b2014-09-23 09:33:00 +00001929 void VisitOMPParallelForSimdDirective(const OMPParallelForSimdDirective *D);
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00001930 void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective *D);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00001931 void VisitOMPTaskDirective(const OMPTaskDirective *D);
Alexey Bataev68446b72014-07-18 07:47:19 +00001932 void VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D);
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00001933 void VisitOMPBarrierDirective(const OMPBarrierDirective *D);
Alexey Bataev2df347a2014-07-18 10:17:07 +00001934 void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00001935 void VisitOMPTaskgroupDirective(const OMPTaskgroupDirective *D);
Alexey Bataev6d4ed052015-07-01 06:57:41 +00001936 void
1937 VisitOMPCancellationPointDirective(const OMPCancellationPointDirective *D);
Alexey Bataev80909872015-07-02 11:25:17 +00001938 void VisitOMPCancelDirective(const OMPCancelDirective *D);
Alexey Bataev6125da92014-07-21 11:26:11 +00001939 void VisitOMPFlushDirective(const OMPFlushDirective *D);
Alexey Bataev9fb6e642014-07-22 06:45:04 +00001940 void VisitOMPOrderedDirective(const OMPOrderedDirective *D);
Alexey Bataev0162e452014-07-22 10:10:35 +00001941 void VisitOMPAtomicDirective(const OMPAtomicDirective *D);
Alexey Bataev0bd520b2014-09-19 08:19:49 +00001942 void VisitOMPTargetDirective(const OMPTargetDirective *D);
Michael Wong65f367f2015-07-21 13:44:28 +00001943 void VisitOMPTargetDataDirective(const OMPTargetDataDirective *D);
Alexey Bataev13314bf2014-10-09 04:18:56 +00001944 void VisitOMPTeamsDirective(const OMPTeamsDirective *D);
Alexey Bataev49f6e782015-12-01 04:18:41 +00001945 void VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *D);
Alexey Bataev0a6ed842015-12-03 09:40:15 +00001946 void VisitOMPTaskLoopSimdDirective(const OMPTaskLoopSimdDirective *D);
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00001947 void VisitOMPDistributeDirective(const OMPDistributeDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001948
Guy Benyei11169dd2012-12-18 14:30:41 +00001949private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001950 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001951 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1952 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001953 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1954 void AddStmt(const Stmt *S);
1955 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001956 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001957 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001958 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001959};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00001960} // end anonyous namespace
Guy Benyei11169dd2012-12-18 14:30:41 +00001961
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001962void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001963 // 'S' should always be non-null, since it comes from the
1964 // statement we are visiting.
1965 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1966}
1967
1968void
1969EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1970 if (Qualifier)
1971 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1972}
1973
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001974void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001975 if (S)
1976 WL.push_back(StmtVisit(S, Parent));
1977}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001978void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001979 if (D)
1980 WL.push_back(DeclVisit(D, Parent, isFirst));
1981}
1982void EnqueueVisitor::
1983 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1984 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001985 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001986}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001987void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001988 if (D)
1989 WL.push_back(MemberRefVisit(D, L, Parent));
1990}
1991void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1992 if (TI)
1993 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1994 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001995void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001996 unsigned size = WL.size();
Benjamin Kramer642f1732015-07-02 21:03:14 +00001997 for (const Stmt *SubStmt : S->children()) {
1998 AddStmt(SubStmt);
Guy Benyei11169dd2012-12-18 14:30:41 +00001999 }
2000 if (size == WL.size())
2001 return;
2002 // Now reverse the entries we just added. This will match the DFS
2003 // ordering performed by the worklist.
2004 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2005 std::reverse(I, E);
2006}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002007namespace {
2008class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
2009 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00002010 /// \brief Process clauses with list of variables.
2011 template <typename T>
2012 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002013public:
2014 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
2015#define OPENMP_CLAUSE(Name, Class) \
2016 void Visit##Class(const Class *C);
2017#include "clang/Basic/OpenMPKinds.def"
2018};
2019
Alexey Bataevaadd52e2014-02-13 05:29:23 +00002020void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
2021 Visitor->AddStmt(C->getCondition());
2022}
2023
Alexey Bataev3778b602014-07-17 07:32:53 +00002024void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
2025 Visitor->AddStmt(C->getCondition());
2026}
2027
Alexey Bataev568a8332014-03-06 06:15:19 +00002028void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
2029 Visitor->AddStmt(C->getNumThreads());
2030}
2031
Alexey Bataev62c87d22014-03-21 04:51:18 +00002032void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
2033 Visitor->AddStmt(C->getSafelen());
2034}
2035
Alexey Bataev66b15b52015-08-21 11:14:16 +00002036void OMPClauseEnqueue::VisitOMPSimdlenClause(const OMPSimdlenClause *C) {
2037 Visitor->AddStmt(C->getSimdlen());
2038}
2039
Alexander Musman8bd31e62014-05-27 15:12:19 +00002040void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
2041 Visitor->AddStmt(C->getNumForLoops());
2042}
2043
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002044void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00002045
Alexey Bataevbcbadb62014-05-06 06:04:14 +00002046void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
2047
Alexey Bataev56dafe82014-06-20 07:16:17 +00002048void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
2049 Visitor->AddStmt(C->getChunkSize());
Alexey Bataev040d5402015-05-12 08:35:28 +00002050 Visitor->AddStmt(C->getHelperChunkSize());
Alexey Bataev56dafe82014-06-20 07:16:17 +00002051}
2052
Alexey Bataev10e775f2015-07-30 11:36:16 +00002053void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *C) {
2054 Visitor->AddStmt(C->getNumForLoops());
2055}
Alexey Bataev142e1fc2014-06-20 09:44:06 +00002056
Alexey Bataev236070f2014-06-20 11:19:47 +00002057void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
2058
Alexey Bataev7aea99a2014-07-17 12:19:31 +00002059void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
2060
Alexey Bataev74ba3a52014-07-17 12:47:03 +00002061void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
2062
Alexey Bataevf98b00c2014-07-23 02:27:21 +00002063void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}
2064
Alexey Bataevdea47612014-07-23 07:46:59 +00002065void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {}
2066
Alexey Bataev67a4f222014-07-23 10:25:33 +00002067void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {}
2068
Alexey Bataev459dec02014-07-24 06:46:57 +00002069void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}
2070
Alexey Bataev82bad8b2014-07-24 08:55:34 +00002071void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
2072
Alexey Bataev346265e2015-09-25 10:37:12 +00002073void OMPClauseEnqueue::VisitOMPThreadsClause(const OMPThreadsClause *) {}
2074
Alexey Bataevd14d1e62015-09-28 06:39:35 +00002075void OMPClauseEnqueue::VisitOMPSIMDClause(const OMPSIMDClause *) {}
2076
Alexey Bataevb825de12015-12-07 10:51:44 +00002077void OMPClauseEnqueue::VisitOMPNogroupClause(const OMPNogroupClause *) {}
2078
Michael Wonge710d542015-08-07 16:16:36 +00002079void OMPClauseEnqueue::VisitOMPDeviceClause(const OMPDeviceClause *C) {
2080 Visitor->AddStmt(C->getDevice());
2081}
2082
Kelvin Li099bb8c2015-11-24 20:50:12 +00002083void OMPClauseEnqueue::VisitOMPNumTeamsClause(const OMPNumTeamsClause *C) {
2084 Visitor->AddStmt(C->getNumTeams());
2085}
2086
Kelvin Lia15fb1a2015-11-27 18:47:36 +00002087void OMPClauseEnqueue::VisitOMPThreadLimitClause(const OMPThreadLimitClause *C) {
2088 Visitor->AddStmt(C->getThreadLimit());
2089}
2090
Alexey Bataeva0569352015-12-01 10:17:31 +00002091void OMPClauseEnqueue::VisitOMPPriorityClause(const OMPPriorityClause *C) {
2092 Visitor->AddStmt(C->getPriority());
2093}
2094
Alexey Bataev1fd4aed2015-12-07 12:52:51 +00002095void OMPClauseEnqueue::VisitOMPGrainsizeClause(const OMPGrainsizeClause *C) {
2096 Visitor->AddStmt(C->getGrainsize());
2097}
2098
Alexey Bataev382967a2015-12-08 12:06:20 +00002099void OMPClauseEnqueue::VisitOMPNumTasksClause(const OMPNumTasksClause *C) {
2100 Visitor->AddStmt(C->getNumTasks());
2101}
2102
Alexey Bataev28c75412015-12-15 08:19:24 +00002103void OMPClauseEnqueue::VisitOMPHintClause(const OMPHintClause *C) {
2104 Visitor->AddStmt(C->getHint());
2105}
2106
Alexey Bataev756c1962013-09-24 03:17:45 +00002107template<typename T>
2108void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Alexey Bataev03b340a2014-10-21 03:16:40 +00002109 for (const auto *I : Node->varlists()) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00002110 Visitor->AddStmt(I);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002111 }
Alexey Bataev756c1962013-09-24 03:17:45 +00002112}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002113
2114void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002115 VisitOMPClauseList(C);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002116 for (const auto *E : C->private_copies()) {
2117 Visitor->AddStmt(E);
2118 }
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002119}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002120void OMPClauseEnqueue::VisitOMPFirstprivateClause(
2121 const OMPFirstprivateClause *C) {
2122 VisitOMPClauseList(C);
2123}
Alexander Musman1bb328c2014-06-04 13:06:39 +00002124void OMPClauseEnqueue::VisitOMPLastprivateClause(
2125 const OMPLastprivateClause *C) {
2126 VisitOMPClauseList(C);
Alexey Bataev38e89532015-04-16 04:54:05 +00002127 for (auto *E : C->private_copies()) {
2128 Visitor->AddStmt(E);
2129 }
2130 for (auto *E : C->source_exprs()) {
2131 Visitor->AddStmt(E);
2132 }
2133 for (auto *E : C->destination_exprs()) {
2134 Visitor->AddStmt(E);
2135 }
2136 for (auto *E : C->assignment_ops()) {
2137 Visitor->AddStmt(E);
2138 }
Alexander Musman1bb328c2014-06-04 13:06:39 +00002139}
Alexey Bataev758e55e2013-09-06 18:03:48 +00002140void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002141 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00002142}
Alexey Bataevc5e02582014-06-16 07:08:35 +00002143void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
2144 VisitOMPClauseList(C);
Alexey Bataevf24e7b12015-10-08 09:10:53 +00002145 for (auto *E : C->privates()) {
2146 Visitor->AddStmt(E);
2147 }
Alexey Bataev794ba0d2015-04-10 10:43:45 +00002148 for (auto *E : C->lhs_exprs()) {
2149 Visitor->AddStmt(E);
2150 }
2151 for (auto *E : C->rhs_exprs()) {
2152 Visitor->AddStmt(E);
2153 }
2154 for (auto *E : C->reduction_ops()) {
2155 Visitor->AddStmt(E);
2156 }
Alexey Bataevc5e02582014-06-16 07:08:35 +00002157}
Alexander Musman8dba6642014-04-22 13:09:42 +00002158void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2159 VisitOMPClauseList(C);
Alexey Bataevbd9fec12015-08-18 06:47:21 +00002160 for (const auto *E : C->privates()) {
2161 Visitor->AddStmt(E);
2162 }
Alexander Musman3276a272015-03-21 10:12:56 +00002163 for (const auto *E : C->inits()) {
2164 Visitor->AddStmt(E);
2165 }
2166 for (const auto *E : C->updates()) {
2167 Visitor->AddStmt(E);
2168 }
2169 for (const auto *E : C->finals()) {
2170 Visitor->AddStmt(E);
2171 }
Alexander Musman8dba6642014-04-22 13:09:42 +00002172 Visitor->AddStmt(C->getStep());
Alexander Musman3276a272015-03-21 10:12:56 +00002173 Visitor->AddStmt(C->getCalcStep());
Alexander Musman8dba6642014-04-22 13:09:42 +00002174}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002175void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2176 VisitOMPClauseList(C);
2177 Visitor->AddStmt(C->getAlignment());
2178}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002179void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2180 VisitOMPClauseList(C);
Alexey Bataevf56f98c2015-04-16 05:39:01 +00002181 for (auto *E : C->source_exprs()) {
2182 Visitor->AddStmt(E);
2183 }
2184 for (auto *E : C->destination_exprs()) {
2185 Visitor->AddStmt(E);
2186 }
2187 for (auto *E : C->assignment_ops()) {
2188 Visitor->AddStmt(E);
2189 }
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002190}
Alexey Bataevbae9a792014-06-27 10:37:06 +00002191void
2192OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
2193 VisitOMPClauseList(C);
Alexey Bataeva63048e2015-03-23 06:18:07 +00002194 for (auto *E : C->source_exprs()) {
2195 Visitor->AddStmt(E);
2196 }
2197 for (auto *E : C->destination_exprs()) {
2198 Visitor->AddStmt(E);
2199 }
2200 for (auto *E : C->assignment_ops()) {
2201 Visitor->AddStmt(E);
2202 }
Alexey Bataevbae9a792014-06-27 10:37:06 +00002203}
Alexey Bataev6125da92014-07-21 11:26:11 +00002204void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2205 VisitOMPClauseList(C);
2206}
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +00002207void OMPClauseEnqueue::VisitOMPDependClause(const OMPDependClause *C) {
2208 VisitOMPClauseList(C);
2209}
Kelvin Li0bff7af2015-11-23 05:32:03 +00002210void OMPClauseEnqueue::VisitOMPMapClause(const OMPMapClause *C) {
2211 VisitOMPClauseList(C);
2212}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002213}
Alexey Bataev756c1962013-09-24 03:17:45 +00002214
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002215void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2216 unsigned size = WL.size();
2217 OMPClauseEnqueue Visitor(this);
2218 Visitor.Visit(S);
2219 if (size == WL.size())
2220 return;
2221 // Now reverse the entries we just added. This will match the DFS
2222 // ordering performed by the worklist.
2223 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2224 std::reverse(I, E);
2225}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002226void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002227 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2228}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002229void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002230 AddDecl(B->getBlockDecl());
2231}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002232void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002233 EnqueueChildren(E);
2234 AddTypeLoc(E->getTypeSourceInfo());
2235}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002236void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
Pete Cooper57d3f142015-07-30 17:22:52 +00002237 for (auto &I : llvm::reverse(S->body()))
2238 AddStmt(I);
Guy Benyei11169dd2012-12-18 14:30:41 +00002239}
2240void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002241VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002242 AddStmt(S->getSubStmt());
2243 AddDeclarationNameInfo(S);
2244 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2245 AddNestedNameSpecifierLoc(QualifierLoc);
2246}
2247
2248void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002249VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002250 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2251 AddDeclarationNameInfo(E);
2252 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2253 AddNestedNameSpecifierLoc(QualifierLoc);
2254 if (!E->isImplicitAccess())
2255 AddStmt(E->getBase());
2256}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002257void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002258 // Enqueue the initializer , if any.
2259 AddStmt(E->getInitializer());
2260 // Enqueue the array size, if any.
2261 AddStmt(E->getArraySize());
2262 // Enqueue the allocated type.
2263 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2264 // Enqueue the placement arguments.
2265 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2266 AddStmt(E->getPlacementArg(I-1));
2267}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002268void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002269 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2270 AddStmt(CE->getArg(I-1));
2271 AddStmt(CE->getCallee());
2272 AddStmt(CE->getArg(0));
2273}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002274void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2275 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002276 // Visit the name of the type being destroyed.
2277 AddTypeLoc(E->getDestroyedTypeInfo());
2278 // Visit the scope type that looks disturbingly like the nested-name-specifier
2279 // but isn't.
2280 AddTypeLoc(E->getScopeTypeInfo());
2281 // Visit the nested-name-specifier.
2282 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2283 AddNestedNameSpecifierLoc(QualifierLoc);
2284 // Visit base expression.
2285 AddStmt(E->getBase());
2286}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002287void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2288 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002289 AddTypeLoc(E->getTypeSourceInfo());
2290}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002291void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2292 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002293 EnqueueChildren(E);
2294 AddTypeLoc(E->getTypeSourceInfo());
2295}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002296void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002297 EnqueueChildren(E);
2298 if (E->isTypeOperand())
2299 AddTypeLoc(E->getTypeOperandSourceInfo());
2300}
2301
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002302void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2303 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002304 EnqueueChildren(E);
2305 AddTypeLoc(E->getTypeSourceInfo());
2306}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002307void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002308 EnqueueChildren(E);
2309 if (E->isTypeOperand())
2310 AddTypeLoc(E->getTypeOperandSourceInfo());
2311}
2312
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002313void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002314 EnqueueChildren(S);
2315 AddDecl(S->getExceptionDecl());
2316}
2317
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002318void EnqueueVisitor::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002319 AddStmt(S->getBody());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002320 AddStmt(S->getRangeInit());
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002321 AddDecl(S->getLoopVariable());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002322}
2323
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002324void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002325 if (DR->hasExplicitTemplateArgs()) {
2326 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2327 }
2328 WL.push_back(DeclRefExprParts(DR, Parent));
2329}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002330void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2331 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002332 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2333 AddDeclarationNameInfo(E);
2334 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2335}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002336void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002337 unsigned size = WL.size();
2338 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002339 for (const auto *D : S->decls()) {
2340 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002341 isFirst = false;
2342 }
2343 if (size == WL.size())
2344 return;
2345 // Now reverse the entries we just added. This will match the DFS
2346 // ordering performed by the worklist.
2347 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2348 std::reverse(I, E);
2349}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002350void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002351 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002352 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002353 D = E->designators_rbegin(), DEnd = E->designators_rend();
2354 D != DEnd; ++D) {
2355 if (D->isFieldDesignator()) {
2356 if (FieldDecl *Field = D->getField())
2357 AddMemberRef(Field, D->getFieldLoc());
2358 continue;
2359 }
2360 if (D->isArrayDesignator()) {
2361 AddStmt(E->getArrayIndex(*D));
2362 continue;
2363 }
2364 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2365 AddStmt(E->getArrayRangeEnd(*D));
2366 AddStmt(E->getArrayRangeStart(*D));
2367 }
2368}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002369void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002370 EnqueueChildren(E);
2371 AddTypeLoc(E->getTypeInfoAsWritten());
2372}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002373void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002374 AddStmt(FS->getBody());
2375 AddStmt(FS->getInc());
2376 AddStmt(FS->getCond());
2377 AddDecl(FS->getConditionVariable());
2378 AddStmt(FS->getInit());
2379}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002380void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002381 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2382}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002383void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002384 AddStmt(If->getElse());
2385 AddStmt(If->getThen());
2386 AddStmt(If->getCond());
2387 AddDecl(If->getConditionVariable());
2388}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002389void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002390 // We care about the syntactic form of the initializer list, only.
2391 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2392 IE = Syntactic;
2393 EnqueueChildren(IE);
2394}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002395void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002396 WL.push_back(MemberExprParts(M, Parent));
2397
2398 // If the base of the member access expression is an implicit 'this', don't
2399 // visit it.
2400 // FIXME: If we ever want to show these implicit accesses, this will be
2401 // unfortunate. However, clang_getCursor() relies on this behavior.
Argyrios Kyrtzidis58d0e7a2015-03-13 04:40:07 +00002402 if (M->isImplicitAccess())
2403 return;
2404
2405 // Ignore base anonymous struct/union fields, otherwise they will shadow the
2406 // real field that that we are interested in.
2407 if (auto *SubME = dyn_cast<MemberExpr>(M->getBase())) {
2408 if (auto *FD = dyn_cast_or_null<FieldDecl>(SubME->getMemberDecl())) {
2409 if (FD->isAnonymousStructOrUnion()) {
2410 AddStmt(SubME->getBase());
2411 return;
2412 }
2413 }
2414 }
2415
2416 AddStmt(M->getBase());
Guy Benyei11169dd2012-12-18 14:30:41 +00002417}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002418void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002419 AddTypeLoc(E->getEncodedTypeSourceInfo());
2420}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002421void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002422 EnqueueChildren(M);
2423 AddTypeLoc(M->getClassReceiverTypeInfo());
2424}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002425void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002426 // Visit the components of the offsetof expression.
2427 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2428 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2429 const OffsetOfNode &Node = E->getComponent(I-1);
2430 switch (Node.getKind()) {
2431 case OffsetOfNode::Array:
2432 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2433 break;
2434 case OffsetOfNode::Field:
2435 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2436 break;
2437 case OffsetOfNode::Identifier:
2438 case OffsetOfNode::Base:
2439 continue;
2440 }
2441 }
2442 // Visit the type into which we're computing the offset.
2443 AddTypeLoc(E->getTypeSourceInfo());
2444}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002445void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002446 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2447 WL.push_back(OverloadExprParts(E, Parent));
2448}
2449void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002450 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002451 EnqueueChildren(E);
2452 if (E->isArgumentType())
2453 AddTypeLoc(E->getArgumentTypeInfo());
2454}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002455void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002456 EnqueueChildren(S);
2457}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002458void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002459 AddStmt(S->getBody());
2460 AddStmt(S->getCond());
2461 AddDecl(S->getConditionVariable());
2462}
2463
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002464void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002465 AddStmt(W->getBody());
2466 AddStmt(W->getCond());
2467 AddDecl(W->getConditionVariable());
2468}
2469
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002470void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002471 for (unsigned I = E->getNumArgs(); I > 0; --I)
2472 AddTypeLoc(E->getArg(I-1));
2473}
2474
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002475void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002476 AddTypeLoc(E->getQueriedTypeSourceInfo());
2477}
2478
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002479void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002480 EnqueueChildren(E);
2481}
2482
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002483void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002484 VisitOverloadExpr(U);
2485 if (!U->isImplicitAccess())
2486 AddStmt(U->getBase());
2487}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002488void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002489 AddStmt(E->getSubExpr());
2490 AddTypeLoc(E->getWrittenTypeInfo());
2491}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002492void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002493 WL.push_back(SizeOfPackExprParts(E, Parent));
2494}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002495void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002496 // If the opaque value has a source expression, just transparently
2497 // visit that. This is useful for (e.g.) pseudo-object expressions.
2498 if (Expr *SourceExpr = E->getSourceExpr())
2499 return Visit(SourceExpr);
2500}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002501void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002502 AddStmt(E->getBody());
2503 WL.push_back(LambdaExprParts(E, Parent));
2504}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002505void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002506 // Treat the expression like its syntactic form.
2507 Visit(E->getSyntacticForm());
2508}
2509
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002510void EnqueueVisitor::VisitOMPExecutableDirective(
2511 const OMPExecutableDirective *D) {
2512 EnqueueChildren(D);
2513 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2514 E = D->clauses().end();
2515 I != E; ++I)
2516 EnqueueChildren(*I);
2517}
2518
Alexander Musman3aaab662014-08-19 11:27:13 +00002519void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
2520 VisitOMPExecutableDirective(D);
2521}
2522
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002523void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2524 VisitOMPExecutableDirective(D);
2525}
2526
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002527void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002528 VisitOMPLoopDirective(D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002529}
2530
Alexey Bataevf29276e2014-06-18 04:14:57 +00002531void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002532 VisitOMPLoopDirective(D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002533}
2534
Alexander Musmanf82886e2014-09-18 05:12:34 +00002535void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
2536 VisitOMPLoopDirective(D);
2537}
2538
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002539void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2540 VisitOMPExecutableDirective(D);
2541}
2542
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002543void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2544 VisitOMPExecutableDirective(D);
2545}
2546
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002547void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2548 VisitOMPExecutableDirective(D);
2549}
2550
Alexander Musman80c22892014-07-17 08:54:58 +00002551void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2552 VisitOMPExecutableDirective(D);
2553}
2554
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002555void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2556 VisitOMPExecutableDirective(D);
2557 AddDeclarationNameInfo(D);
2558}
2559
Alexey Bataev4acb8592014-07-07 13:01:15 +00002560void
2561EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002562 VisitOMPLoopDirective(D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002563}
2564
Alexander Musmane4e893b2014-09-23 09:33:00 +00002565void EnqueueVisitor::VisitOMPParallelForSimdDirective(
2566 const OMPParallelForSimdDirective *D) {
2567 VisitOMPLoopDirective(D);
2568}
2569
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002570void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2571 const OMPParallelSectionsDirective *D) {
2572 VisitOMPExecutableDirective(D);
2573}
2574
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002575void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2576 VisitOMPExecutableDirective(D);
2577}
2578
Alexey Bataev68446b72014-07-18 07:47:19 +00002579void
2580EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2581 VisitOMPExecutableDirective(D);
2582}
2583
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002584void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2585 VisitOMPExecutableDirective(D);
2586}
2587
Alexey Bataev2df347a2014-07-18 10:17:07 +00002588void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2589 VisitOMPExecutableDirective(D);
2590}
2591
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002592void EnqueueVisitor::VisitOMPTaskgroupDirective(
2593 const OMPTaskgroupDirective *D) {
2594 VisitOMPExecutableDirective(D);
2595}
2596
Alexey Bataev6125da92014-07-21 11:26:11 +00002597void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2598 VisitOMPExecutableDirective(D);
2599}
2600
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002601void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2602 VisitOMPExecutableDirective(D);
2603}
2604
Alexey Bataev0162e452014-07-22 10:10:35 +00002605void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2606 VisitOMPExecutableDirective(D);
2607}
2608
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002609void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
2610 VisitOMPExecutableDirective(D);
2611}
2612
Michael Wong65f367f2015-07-21 13:44:28 +00002613void EnqueueVisitor::VisitOMPTargetDataDirective(const
2614 OMPTargetDataDirective *D) {
2615 VisitOMPExecutableDirective(D);
2616}
2617
Alexey Bataev13314bf2014-10-09 04:18:56 +00002618void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {
2619 VisitOMPExecutableDirective(D);
2620}
2621
Alexey Bataev6d4ed052015-07-01 06:57:41 +00002622void EnqueueVisitor::VisitOMPCancellationPointDirective(
2623 const OMPCancellationPointDirective *D) {
2624 VisitOMPExecutableDirective(D);
2625}
2626
Alexey Bataev80909872015-07-02 11:25:17 +00002627void EnqueueVisitor::VisitOMPCancelDirective(const OMPCancelDirective *D) {
2628 VisitOMPExecutableDirective(D);
2629}
2630
Alexey Bataev49f6e782015-12-01 04:18:41 +00002631void EnqueueVisitor::VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *D) {
2632 VisitOMPLoopDirective(D);
2633}
2634
Alexey Bataev0a6ed842015-12-03 09:40:15 +00002635void EnqueueVisitor::VisitOMPTaskLoopSimdDirective(
2636 const OMPTaskLoopSimdDirective *D) {
2637 VisitOMPLoopDirective(D);
2638}
2639
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00002640void EnqueueVisitor::VisitOMPDistributeDirective(
2641 const OMPDistributeDirective *D) {
2642 VisitOMPLoopDirective(D);
2643}
2644
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002645void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002646 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2647}
2648
2649bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2650 if (RegionOfInterest.isValid()) {
2651 SourceRange Range = getRawCursorExtent(C);
2652 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2653 return false;
2654 }
2655 return true;
2656}
2657
2658bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2659 while (!WL.empty()) {
2660 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002661 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002662
2663 // Set the Parent field, then back to its old value once we're done.
2664 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2665
2666 switch (LI.getKind()) {
2667 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002668 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002669 if (!D)
2670 continue;
2671
2672 // For now, perform default visitation for Decls.
2673 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2674 cast<DeclVisit>(&LI)->isFirst())))
2675 return true;
2676
2677 continue;
2678 }
2679 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2680 const ASTTemplateArgumentListInfo *ArgList =
2681 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2682 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2683 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2684 Arg != ArgEnd; ++Arg) {
2685 if (VisitTemplateArgumentLoc(*Arg))
2686 return true;
2687 }
2688 continue;
2689 }
2690 case VisitorJob::TypeLocVisitKind: {
2691 // Perform default visitation for TypeLocs.
2692 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2693 return true;
2694 continue;
2695 }
2696 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002697 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002698 if (LabelStmt *stmt = LS->getStmt()) {
2699 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2700 TU))) {
2701 return true;
2702 }
2703 }
2704 continue;
2705 }
2706
2707 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2708 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2709 if (VisitNestedNameSpecifierLoc(V->get()))
2710 return true;
2711 continue;
2712 }
2713
2714 case VisitorJob::DeclarationNameInfoVisitKind: {
2715 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2716 ->get()))
2717 return true;
2718 continue;
2719 }
2720 case VisitorJob::MemberRefVisitKind: {
2721 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2722 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2723 return true;
2724 continue;
2725 }
2726 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002727 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002728 if (!S)
2729 continue;
2730
2731 // Update the current cursor.
2732 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2733 if (!IsInRegionOfInterest(Cursor))
2734 continue;
2735 switch (Visitor(Cursor, Parent, ClientData)) {
2736 case CXChildVisit_Break: return true;
2737 case CXChildVisit_Continue: break;
2738 case CXChildVisit_Recurse:
2739 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002740 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002741 EnqueueWorkList(WL, S);
2742 break;
2743 }
2744 continue;
2745 }
2746 case VisitorJob::MemberExprPartsKind: {
2747 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002748 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002749
2750 // Visit the nested-name-specifier
2751 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2752 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2753 return true;
2754
2755 // Visit the declaration name.
2756 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2757 return true;
2758
2759 // Visit the explicitly-specified template arguments, if any.
2760 if (M->hasExplicitTemplateArgs()) {
2761 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2762 *ArgEnd = Arg + M->getNumTemplateArgs();
2763 Arg != ArgEnd; ++Arg) {
2764 if (VisitTemplateArgumentLoc(*Arg))
2765 return true;
2766 }
2767 }
2768 continue;
2769 }
2770 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002771 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002772 // Visit nested-name-specifier, if present.
2773 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2774 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2775 return true;
2776 // Visit declaration name.
2777 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2778 return true;
2779 continue;
2780 }
2781 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002782 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002783 // Visit the nested-name-specifier.
2784 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2785 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2786 return true;
2787 // Visit the declaration name.
2788 if (VisitDeclarationNameInfo(O->getNameInfo()))
2789 return true;
2790 // Visit the overloaded declaration reference.
2791 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2792 return true;
2793 continue;
2794 }
2795 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002796 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002797 NamedDecl *Pack = E->getPack();
2798 if (isa<TemplateTypeParmDecl>(Pack)) {
2799 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2800 E->getPackLoc(), TU)))
2801 return true;
2802
2803 continue;
2804 }
2805
2806 if (isa<TemplateTemplateParmDecl>(Pack)) {
2807 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2808 E->getPackLoc(), TU)))
2809 return true;
2810
2811 continue;
2812 }
2813
2814 // Non-type template parameter packs and function parameter packs are
2815 // treated like DeclRefExpr cursors.
2816 continue;
2817 }
2818
2819 case VisitorJob::LambdaExprPartsKind: {
2820 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002821 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002822 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2823 CEnd = E->explicit_capture_end();
2824 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002825 // FIXME: Lambda init-captures.
2826 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002827 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002828
Guy Benyei11169dd2012-12-18 14:30:41 +00002829 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2830 C->getLocation(),
2831 TU)))
2832 return true;
2833 }
2834
2835 // Visit parameters and return type, if present.
2836 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2837 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2838 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2839 // Visit the whole type.
2840 if (Visit(TL))
2841 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002842 } else if (FunctionProtoTypeLoc Proto =
2843 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002844 if (E->hasExplicitParameters()) {
2845 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002846 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2847 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002848 return true;
2849 } else {
2850 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002851 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002852 return true;
2853 }
2854 }
2855 }
2856 break;
2857 }
2858
2859 case VisitorJob::PostChildrenVisitKind:
2860 if (PostChildrenVisitor(Parent, ClientData))
2861 return true;
2862 break;
2863 }
2864 }
2865 return false;
2866}
2867
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002868bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002869 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002870 if (!WorkListFreeList.empty()) {
2871 WL = WorkListFreeList.back();
2872 WL->clear();
2873 WorkListFreeList.pop_back();
2874 }
2875 else {
2876 WL = new VisitorWorkList();
2877 WorkListCache.push_back(WL);
2878 }
2879 EnqueueWorkList(*WL, S);
2880 bool result = RunVisitorWorkList(*WL);
2881 WorkListFreeList.push_back(WL);
2882 return result;
2883}
2884
2885namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002886typedef SmallVector<SourceRange, 4> RefNamePieces;
Craig Topper69186e72014-06-08 08:38:04 +00002887RefNamePieces
2888buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
Craig Toppere335f252015-10-04 04:53:55 +00002889 const DeclarationNameInfo &NI, SourceRange QLoc,
Craig Topper69186e72014-06-08 08:38:04 +00002890 const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002891 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2892 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2893 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2894
2895 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2896
2897 RefNamePieces Pieces;
2898
2899 if (WantQualifier && QLoc.isValid())
2900 Pieces.push_back(QLoc);
2901
2902 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2903 Pieces.push_back(NI.getLoc());
2904
2905 if (WantTemplateArgs && TemplateArgs)
2906 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2907 TemplateArgs->RAngleLoc));
2908
2909 if (Kind == DeclarationName::CXXOperatorName) {
2910 Pieces.push_back(SourceLocation::getFromRawEncoding(
2911 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2912 Pieces.push_back(SourceLocation::getFromRawEncoding(
2913 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2914 }
2915
2916 if (WantSinglePiece) {
2917 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2918 Pieces.clear();
2919 Pieces.push_back(R);
2920 }
2921
2922 return Pieces;
2923}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002924}
Guy Benyei11169dd2012-12-18 14:30:41 +00002925
2926//===----------------------------------------------------------------------===//
2927// Misc. API hooks.
2928//===----------------------------------------------------------------------===//
2929
Chad Rosier05c71aa2013-03-27 18:28:23 +00002930static void fatal_error_handler(void *user_data, const std::string& reason,
2931 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002932 // Write the result out to stderr avoiding errs() because raw_ostreams can
2933 // call report_fatal_error.
2934 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2935 ::abort();
2936}
2937
Chandler Carruth66660742014-06-27 16:37:27 +00002938namespace {
2939struct RegisterFatalErrorHandler {
2940 RegisterFatalErrorHandler() {
2941 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2942 }
2943};
2944}
2945
2946static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
2947
Guy Benyei11169dd2012-12-18 14:30:41 +00002948extern "C" {
2949CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2950 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002951 // We use crash recovery to make some of our APIs more reliable, implicitly
2952 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002953 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2954 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002955
Chandler Carruth66660742014-06-27 16:37:27 +00002956 // Look through the managed static to trigger construction of the managed
2957 // static which registers our fatal error handler. This ensures it is only
2958 // registered once.
2959 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00002960
Adrian Prantlbc068582015-07-08 01:00:30 +00002961 // Initialize targets for clang module support.
2962 llvm::InitializeAllTargets();
2963 llvm::InitializeAllTargetMCs();
2964 llvm::InitializeAllAsmPrinters();
2965 llvm::InitializeAllAsmParsers();
2966
Adrian Prantlfb2398d2015-07-17 01:19:54 +00002967 CIndexer *CIdxr = new CIndexer();
2968
Guy Benyei11169dd2012-12-18 14:30:41 +00002969 if (excludeDeclarationsFromPCH)
2970 CIdxr->setOnlyLocalDecls();
2971 if (displayDiagnostics)
2972 CIdxr->setDisplayDiagnostics();
2973
2974 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2975 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2976 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2977 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2978 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2979 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2980
2981 return CIdxr;
2982}
2983
2984void clang_disposeIndex(CXIndex CIdx) {
2985 if (CIdx)
2986 delete static_cast<CIndexer *>(CIdx);
2987}
2988
2989void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2990 if (CIdx)
2991 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2992}
2993
2994unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2995 if (CIdx)
2996 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2997 return 0;
2998}
2999
3000void clang_toggleCrashRecovery(unsigned isEnabled) {
3001 if (isEnabled)
3002 llvm::CrashRecoveryContext::Enable();
3003 else
3004 llvm::CrashRecoveryContext::Disable();
3005}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003006
Guy Benyei11169dd2012-12-18 14:30:41 +00003007CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
3008 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003009 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003010 enum CXErrorCode Result =
3011 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00003012 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003013 assert((TU && Result == CXError_Success) ||
3014 (!TU && Result != CXError_Success));
3015 return TU;
3016}
3017
3018enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
3019 const char *ast_filename,
3020 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003021 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00003022 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003023
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003024 if (!CIdx || !ast_filename || !out_TU)
3025 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00003026
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00003027 LOG_FUNC_SECTION {
3028 *Log << ast_filename;
3029 }
3030
Guy Benyei11169dd2012-12-18 14:30:41 +00003031 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3032 FileSystemOptions FileSystemOpts;
3033
Justin Bognerd512c1e2014-10-15 00:33:06 +00003034 IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
3035 CompilerInstance::createDiagnostics(new DiagnosticOptions());
David Blaikie6f7382d2014-08-10 19:08:04 +00003036 std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
Adrian Prantlfb2398d2015-07-17 01:19:54 +00003037 ast_filename, CXXIdx->getPCHContainerOperations()->getRawReader(), Diags,
Adrian Prantl6b21ab22015-08-27 19:46:20 +00003038 FileSystemOpts, /*UseDebugInfo=*/false,
3039 CXXIdx->getOnlyLocalDecls(), None,
David Blaikie6f7382d2014-08-10 19:08:04 +00003040 /*CaptureDiagnostics=*/true,
3041 /*AllowPCHWithCompilerErrors=*/true,
3042 /*UserFilesAreVolatile=*/true);
3043 *out_TU = MakeCXTranslationUnit(CXXIdx, AU.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003044 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003045}
3046
3047unsigned clang_defaultEditingTranslationUnitOptions() {
3048 return CXTranslationUnit_PrecompiledPreamble |
3049 CXTranslationUnit_CacheCompletionResults;
3050}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003051
Guy Benyei11169dd2012-12-18 14:30:41 +00003052CXTranslationUnit
3053clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
3054 const char *source_filename,
3055 int num_command_line_args,
3056 const char * const *command_line_args,
3057 unsigned num_unsaved_files,
3058 struct CXUnsavedFile *unsaved_files) {
3059 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
3060 return clang_parseTranslationUnit(CIdx, source_filename,
3061 command_line_args, num_command_line_args,
3062 unsaved_files, num_unsaved_files,
3063 Options);
3064}
3065
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003066static CXErrorCode
3067clang_parseTranslationUnit_Impl(CXIndex CIdx, const char *source_filename,
3068 const char *const *command_line_args,
3069 int num_command_line_args,
3070 ArrayRef<CXUnsavedFile> unsaved_files,
3071 unsigned options, CXTranslationUnit *out_TU) {
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003072 // Set up the initial return values.
3073 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00003074 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003075
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003076 // Check arguments.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003077 if (!CIdx || !out_TU)
3078 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003079
Guy Benyei11169dd2012-12-18 14:30:41 +00003080 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3081
3082 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3083 setThreadBackgroundPriority();
3084
3085 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
3086 // FIXME: Add a flag for modules.
3087 TranslationUnitKind TUKind
3088 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00003089 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00003090 = options & CXTranslationUnit_CacheCompletionResults;
3091 bool IncludeBriefCommentsInCodeCompletion
3092 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
3093 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
3094 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
3095
3096 // Configure the diagnostics.
3097 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00003098 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00003099
3100 // Recover resources if we crash before exiting this function.
3101 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
3102 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00003103 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00003104
Ahmed Charlesb8984322014-03-07 20:03:18 +00003105 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3106 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003107
3108 // Recover resources if we crash before exiting this function.
3109 llvm::CrashRecoveryContextCleanupRegistrar<
3110 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3111
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003112 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003113 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003114 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003115 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003116 }
3117
Ahmed Charlesb8984322014-03-07 20:03:18 +00003118 std::unique_ptr<std::vector<const char *>> Args(
3119 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003120
3121 // Recover resources if we crash before exiting this method.
3122 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
3123 ArgsCleanup(Args.get());
3124
3125 // Since the Clang C library is primarily used by batch tools dealing with
3126 // (often very broken) source code, where spell-checking can have a
3127 // significant negative impact on performance (particularly when
3128 // precompiled headers are involved), we disable it by default.
3129 // Only do this if we haven't found a spell-checking-related argument.
3130 bool FoundSpellCheckingArgument = false;
3131 for (int I = 0; I != num_command_line_args; ++I) {
3132 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
3133 strcmp(command_line_args[I], "-fspell-checking") == 0) {
3134 FoundSpellCheckingArgument = true;
3135 break;
3136 }
3137 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003138 Args->insert(Args->end(), command_line_args,
3139 command_line_args + num_command_line_args);
3140
Benjamin Kramerc02670e2015-11-18 16:14:27 +00003141 if (!FoundSpellCheckingArgument)
3142 Args->insert(Args->begin() + 1, "-fno-spell-checking");
3143
Guy Benyei11169dd2012-12-18 14:30:41 +00003144 // The 'source_filename' argument is optional. If the caller does not
3145 // specify it then it is assumed that the source file is specified
3146 // in the actual argument list.
3147 // Put the source file after command_line_args otherwise if '-x' flag is
3148 // present it will be unused.
3149 if (source_filename)
3150 Args->push_back(source_filename);
3151
3152 // Do we need the detailed preprocessing record?
3153 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
3154 Args->push_back("-Xclang");
3155 Args->push_back("-detailed-preprocessing-record");
3156 }
3157
3158 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00003159 std::unique_ptr<ASTUnit> ErrUnit;
3160 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003161 Args->data(), Args->data() + Args->size(),
3162 CXXIdx->getPCHContainerOperations(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00003163 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
3164 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
3165 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
3166 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
3167 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
Argyrios Kyrtzidisa3e2ff12015-11-20 03:36:21 +00003168 /*UserFilesAreVolatile=*/true, ForSerialization,
3169 CXXIdx->getPCHContainerOperations()->getRawReader().getFormat(),
3170 &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00003171
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003172 // Early failures in LoadFromCommandLine may return with ErrUnit unset.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003173 if (!Unit && !ErrUnit)
3174 return CXError_ASTReadError;
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003175
Guy Benyei11169dd2012-12-18 14:30:41 +00003176 if (NumErrors != Diags->getClient()->getNumErrors()) {
3177 // Make sure to check that 'Unit' is non-NULL.
3178 if (CXXIdx->getDisplayDiagnostics())
3179 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
3180 }
3181
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003182 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get()))
3183 return CXError_ASTReadError;
3184
3185 *out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
3186 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003187}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003188
3189CXTranslationUnit
3190clang_parseTranslationUnit(CXIndex CIdx,
3191 const char *source_filename,
3192 const char *const *command_line_args,
3193 int num_command_line_args,
3194 struct CXUnsavedFile *unsaved_files,
3195 unsigned num_unsaved_files,
3196 unsigned options) {
3197 CXTranslationUnit TU;
3198 enum CXErrorCode Result = clang_parseTranslationUnit2(
3199 CIdx, source_filename, command_line_args, num_command_line_args,
3200 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00003201 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003202 assert((TU && Result == CXError_Success) ||
3203 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003204 return TU;
3205}
3206
3207enum CXErrorCode clang_parseTranslationUnit2(
Benjamin Kramerc02670e2015-11-18 16:14:27 +00003208 CXIndex CIdx, const char *source_filename,
3209 const char *const *command_line_args, int num_command_line_args,
3210 struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
3211 unsigned options, CXTranslationUnit *out_TU) {
3212 SmallVector<const char *, 4> Args;
3213 Args.push_back("clang");
3214 Args.append(command_line_args, command_line_args + num_command_line_args);
3215 return clang_parseTranslationUnit2FullArgv(
3216 CIdx, source_filename, Args.data(), Args.size(), unsaved_files,
3217 num_unsaved_files, options, out_TU);
3218}
3219
3220enum CXErrorCode clang_parseTranslationUnit2FullArgv(
3221 CXIndex CIdx, const char *source_filename,
3222 const char *const *command_line_args, int num_command_line_args,
3223 struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
3224 unsigned options, CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003225 LOG_FUNC_SECTION {
3226 *Log << source_filename << ": ";
3227 for (int i = 0; i != num_command_line_args; ++i)
3228 *Log << command_line_args[i] << " ";
3229 }
3230
Alp Toker9d85b182014-07-07 01:23:14 +00003231 if (num_unsaved_files && !unsaved_files)
3232 return CXError_InvalidArguments;
3233
Alp Toker5c532982014-07-07 22:42:03 +00003234 CXErrorCode result = CXError_Failure;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003235 auto ParseTranslationUnitImpl = [=, &result] {
3236 result = clang_parseTranslationUnit_Impl(
3237 CIdx, source_filename, command_line_args, num_command_line_args,
3238 llvm::makeArrayRef(unsaved_files, num_unsaved_files), options, out_TU);
3239 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003240 llvm::CrashRecoveryContext CRC;
3241
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003242 if (!RunSafely(CRC, ParseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003243 fprintf(stderr, "libclang: crash detected during parsing: {\n");
3244 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3245 fprintf(stderr, " 'command_line_args' : [");
3246 for (int i = 0; i != num_command_line_args; ++i) {
3247 if (i)
3248 fprintf(stderr, ", ");
3249 fprintf(stderr, "'%s'", command_line_args[i]);
3250 }
3251 fprintf(stderr, "],\n");
3252 fprintf(stderr, " 'unsaved_files' : [");
3253 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3254 if (i)
3255 fprintf(stderr, ", ");
3256 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3257 unsaved_files[i].Length);
3258 }
3259 fprintf(stderr, "],\n");
3260 fprintf(stderr, " 'options' : %d,\n", options);
3261 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003262
3263 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003264 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003265 if (CXTranslationUnit *TU = out_TU)
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003266 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003267 }
Alp Toker5c532982014-07-07 22:42:03 +00003268
3269 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003270}
3271
3272unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
3273 return CXSaveTranslationUnit_None;
3274}
3275
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003276static CXSaveError clang_saveTranslationUnit_Impl(CXTranslationUnit TU,
3277 const char *FileName,
3278 unsigned options) {
3279 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003280 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3281 setThreadBackgroundPriority();
3282
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003283 bool hadError = cxtu::getASTUnit(TU)->Save(FileName);
3284 return hadError ? CXSaveError_Unknown : CXSaveError_None;
Guy Benyei11169dd2012-12-18 14:30:41 +00003285}
3286
3287int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3288 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003289 LOG_FUNC_SECTION {
3290 *Log << TU << ' ' << FileName;
3291 }
3292
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003293 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003294 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003295 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003296 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003297
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003298 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003299 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3300 if (!CXXUnit->hasSema())
3301 return CXSaveError_InvalidTU;
3302
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003303 CXSaveError result;
3304 auto SaveTranslationUnitImpl = [=, &result]() {
3305 result = clang_saveTranslationUnit_Impl(TU, FileName, options);
3306 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003307
3308 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3309 getenv("LIBCLANG_NOTHREADS")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003310 SaveTranslationUnitImpl();
Guy Benyei11169dd2012-12-18 14:30:41 +00003311
3312 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3313 PrintLibclangResourceUsage(TU);
3314
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003315 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003316 }
3317
3318 // We have an AST that has invalid nodes due to compiler errors.
3319 // Use a crash recovery thread for protection.
3320
3321 llvm::CrashRecoveryContext CRC;
3322
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003323 if (!RunSafely(CRC, SaveTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003324 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3325 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3326 fprintf(stderr, " 'options' : %d,\n", options);
3327 fprintf(stderr, "}\n");
3328
3329 return CXSaveError_Unknown;
3330
3331 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3332 PrintLibclangResourceUsage(TU);
3333 }
3334
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003335 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003336}
3337
3338void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3339 if (CTUnit) {
3340 // If the translation unit has been marked as unsafe to free, just discard
3341 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003342 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3343 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003344 return;
3345
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003346 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003347 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003348 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3349 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003350 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003351 delete CTUnit;
3352 }
3353}
3354
3355unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3356 return CXReparse_None;
3357}
3358
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003359static CXErrorCode
3360clang_reparseTranslationUnit_Impl(CXTranslationUnit TU,
3361 ArrayRef<CXUnsavedFile> unsaved_files,
3362 unsigned options) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003363 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003364 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003365 LOG_BAD_TU(TU);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003366 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003367 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003368
3369 // Reset the associated diagnostics.
3370 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003371 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003372
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003373 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003374 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3375 setThreadBackgroundPriority();
3376
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003377 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003378 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003379
3380 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3381 new std::vector<ASTUnit::RemappedFile>());
3382
Guy Benyei11169dd2012-12-18 14:30:41 +00003383 // Recover resources if we crash before exiting this function.
3384 llvm::CrashRecoveryContextCleanupRegistrar<
3385 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003386
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003387 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003388 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003389 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003390 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003391 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003392
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003393 if (!CXXUnit->Reparse(CXXIdx->getPCHContainerOperations(),
3394 *RemappedFiles.get()))
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003395 return CXError_Success;
3396 if (isASTReadError(CXXUnit))
3397 return CXError_ASTReadError;
3398 return CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003399}
3400
3401int clang_reparseTranslationUnit(CXTranslationUnit TU,
3402 unsigned num_unsaved_files,
3403 struct CXUnsavedFile *unsaved_files,
3404 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003405 LOG_FUNC_SECTION {
3406 *Log << TU;
3407 }
3408
Alp Toker9d85b182014-07-07 01:23:14 +00003409 if (num_unsaved_files && !unsaved_files)
3410 return CXError_InvalidArguments;
3411
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003412 CXErrorCode result;
3413 auto ReparseTranslationUnitImpl = [=, &result]() {
3414 result = clang_reparseTranslationUnit_Impl(
3415 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options);
3416 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003417
3418 if (getenv("LIBCLANG_NOTHREADS")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003419 ReparseTranslationUnitImpl();
Alp Toker5c532982014-07-07 22:42:03 +00003420 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003421 }
3422
3423 llvm::CrashRecoveryContext CRC;
3424
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003425 if (!RunSafely(CRC, ReparseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003426 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003427 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003428 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003429 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3430 PrintLibclangResourceUsage(TU);
3431
Alp Toker5c532982014-07-07 22:42:03 +00003432 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003433}
3434
3435
3436CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003437 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003438 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003439 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003440 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003441
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003442 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003443 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003444}
3445
3446CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003447 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003448 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003449 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003450 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003451
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003452 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003453 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3454}
3455
3456} // end: extern "C"
3457
3458//===----------------------------------------------------------------------===//
3459// CXFile Operations.
3460//===----------------------------------------------------------------------===//
3461
3462extern "C" {
3463CXString clang_getFileName(CXFile SFile) {
3464 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003465 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003466
3467 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003468 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003469}
3470
3471time_t clang_getFileTime(CXFile SFile) {
3472 if (!SFile)
3473 return 0;
3474
3475 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3476 return FEnt->getModificationTime();
3477}
3478
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003479CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003480 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003481 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003482 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003483 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003484
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003485 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003486
3487 FileManager &FMgr = CXXUnit->getFileManager();
3488 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3489}
3490
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003491unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3492 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003493 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003494 LOG_BAD_TU(TU);
3495 return 0;
3496 }
3497
3498 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003499 return 0;
3500
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003501 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003502 FileEntry *FEnt = static_cast<FileEntry *>(file);
3503 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3504 .isFileMultipleIncludeGuarded(FEnt);
3505}
3506
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003507int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3508 if (!file || !outID)
3509 return 1;
3510
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003511 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003512 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3513 outID->data[0] = ID.getDevice();
3514 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003515 outID->data[2] = FEnt->getModificationTime();
3516 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003517}
3518
Argyrios Kyrtzidisac3997e2014-08-16 00:26:19 +00003519int clang_File_isEqual(CXFile file1, CXFile file2) {
3520 if (file1 == file2)
3521 return true;
3522
3523 if (!file1 || !file2)
3524 return false;
3525
3526 FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
3527 FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
3528 return FEnt1->getUniqueID() == FEnt2->getUniqueID();
3529}
3530
Guy Benyei11169dd2012-12-18 14:30:41 +00003531} // end: extern "C"
3532
3533//===----------------------------------------------------------------------===//
3534// CXCursor Operations.
3535//===----------------------------------------------------------------------===//
3536
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003537static const Decl *getDeclFromExpr(const Stmt *E) {
3538 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003539 return getDeclFromExpr(CE->getSubExpr());
3540
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003541 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003542 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003543 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003544 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003545 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003546 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003547 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003548 if (PRE->isExplicitProperty())
3549 return PRE->getExplicitProperty();
3550 // It could be messaging both getter and setter as in:
3551 // ++myobj.myprop;
3552 // in which case prefer to associate the setter since it is less obvious
3553 // from inspecting the source that the setter is going to get called.
3554 if (PRE->isMessagingSetter())
3555 return PRE->getImplicitPropertySetter();
3556 return PRE->getImplicitPropertyGetter();
3557 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003558 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003559 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003560 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003561 if (Expr *Src = OVE->getSourceExpr())
3562 return getDeclFromExpr(Src);
3563
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003564 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003565 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003566 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003567 if (!CE->isElidable())
3568 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003569 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003570 return OME->getMethodDecl();
3571
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003572 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003573 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003574 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003575 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3576 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003577 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003578 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3579 isa<ParmVarDecl>(SizeOfPack->getPack()))
3580 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003581
3582 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003583}
3584
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003585static SourceLocation getLocationFromExpr(const Expr *E) {
3586 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003587 return getLocationFromExpr(CE->getSubExpr());
3588
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003589 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003590 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003591 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003592 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003593 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003594 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003595 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003596 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003597 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003598 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003599 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003600 return PropRef->getLocation();
3601
3602 return E->getLocStart();
3603}
3604
Aaron Ballmana85d3f82015-11-12 15:25:06 +00003605static std::string getMangledStructor(std::unique_ptr<MangleContext> &M,
3606 std::unique_ptr<llvm::DataLayout> &DL,
3607 const NamedDecl *ND,
3608 unsigned StructorType) {
3609 std::string FrontendBuf;
3610 llvm::raw_string_ostream FOS(FrontendBuf);
3611
3612 if (const auto *CD = dyn_cast_or_null<CXXConstructorDecl>(ND))
3613 M->mangleCXXCtor(CD, static_cast<CXXCtorType>(StructorType), FOS);
3614 else if (const auto *DD = dyn_cast_or_null<CXXDestructorDecl>(ND))
3615 M->mangleCXXDtor(DD, static_cast<CXXDtorType>(StructorType), FOS);
3616
3617 std::string BackendBuf;
3618 llvm::raw_string_ostream BOS(BackendBuf);
3619
3620 llvm::Mangler::getNameWithPrefix(BOS, llvm::Twine(FOS.str()), *DL);
3621
3622 return BOS.str();
3623}
3624
Guy Benyei11169dd2012-12-18 14:30:41 +00003625extern "C" {
3626
3627unsigned clang_visitChildren(CXCursor parent,
3628 CXCursorVisitor visitor,
3629 CXClientData client_data) {
3630 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3631 /*VisitPreprocessorLast=*/false);
3632 return CursorVis.VisitChildren(parent);
3633}
3634
3635#ifndef __has_feature
3636#define __has_feature(x) 0
3637#endif
3638#if __has_feature(blocks)
3639typedef enum CXChildVisitResult
3640 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3641
3642static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3643 CXClientData client_data) {
3644 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3645 return block(cursor, parent);
3646}
3647#else
3648// If we are compiled with a compiler that doesn't have native blocks support,
3649// define and call the block manually, so the
3650typedef struct _CXChildVisitResult
3651{
3652 void *isa;
3653 int flags;
3654 int reserved;
3655 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3656 CXCursor);
3657} *CXCursorVisitorBlock;
3658
3659static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3660 CXClientData client_data) {
3661 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3662 return block->invoke(block, cursor, parent);
3663}
3664#endif
3665
3666
3667unsigned clang_visitChildrenWithBlock(CXCursor parent,
3668 CXCursorVisitorBlock block) {
3669 return clang_visitChildren(parent, visitWithBlock, block);
3670}
3671
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003672static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003673 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003674 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003675
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003676 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003677 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003678 if (const ObjCPropertyImplDecl *PropImpl =
3679 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003680 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003681 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003682
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003683 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003684 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003685 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003686
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003687 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003688 }
3689
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003690 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003691 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003692
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003693 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003694 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3695 // and returns different names. NamedDecl returns the class name and
3696 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003697 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003698
3699 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003700 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003701
3702 SmallString<1024> S;
3703 llvm::raw_svector_ostream os(S);
3704 ND->printName(os);
3705
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003706 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003707}
3708
3709CXString clang_getCursorSpelling(CXCursor C) {
3710 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003711 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003712
3713 if (clang_isReference(C.kind)) {
3714 switch (C.kind) {
3715 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003716 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003717 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003718 }
3719 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003720 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003721 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003722 }
3723 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003724 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003725 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003726 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003727 }
3728 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003729 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003730 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003731 }
3732 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003733 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003734 assert(Type && "Missing type decl");
3735
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003736 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003737 getAsString());
3738 }
3739 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003740 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003741 assert(Template && "Missing template decl");
3742
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003743 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003744 }
3745
3746 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003747 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003748 assert(NS && "Missing namespace decl");
3749
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003750 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003751 }
3752
3753 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003754 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003755 assert(Field && "Missing member decl");
3756
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003757 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003758 }
3759
3760 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003761 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003762 assert(Label && "Missing label");
3763
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003764 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003765 }
3766
3767 case CXCursor_OverloadedDeclRef: {
3768 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003769 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3770 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003771 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003772 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003773 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003774 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003775 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003776 OverloadedTemplateStorage *Ovl
3777 = Storage.get<OverloadedTemplateStorage*>();
3778 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003779 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003780 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003781 }
3782
3783 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003784 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003785 assert(Var && "Missing variable decl");
3786
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003787 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003788 }
3789
3790 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003791 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003792 }
3793 }
3794
3795 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003796 const Expr *E = getCursorExpr(C);
3797
3798 if (C.kind == CXCursor_ObjCStringLiteral ||
3799 C.kind == CXCursor_StringLiteral) {
3800 const StringLiteral *SLit;
3801 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3802 SLit = OSL->getString();
3803 } else {
3804 SLit = cast<StringLiteral>(E);
3805 }
3806 SmallString<256> Buf;
3807 llvm::raw_svector_ostream OS(Buf);
3808 SLit->outputString(OS);
3809 return cxstring::createDup(OS.str());
3810 }
3811
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003812 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003813 if (D)
3814 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003815 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003816 }
3817
3818 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003819 const Stmt *S = getCursorStmt(C);
3820 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003821 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003822
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003823 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003824 }
3825
3826 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003827 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003828 ->getNameStart());
3829
3830 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003831 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003832 ->getNameStart());
3833
3834 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003835 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003836
3837 if (clang_isDeclaration(C.kind))
3838 return getDeclSpelling(getCursorDecl(C));
3839
3840 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003841 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003842 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003843 }
3844
3845 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003846 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003847 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003848 }
3849
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003850 if (C.kind == CXCursor_PackedAttr) {
3851 return cxstring::createRef("packed");
3852 }
3853
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00003854 if (C.kind == CXCursor_VisibilityAttr) {
3855 const VisibilityAttr *AA = cast<VisibilityAttr>(cxcursor::getCursorAttr(C));
3856 switch (AA->getVisibility()) {
3857 case VisibilityAttr::VisibilityType::Default:
3858 return cxstring::createRef("default");
3859 case VisibilityAttr::VisibilityType::Hidden:
3860 return cxstring::createRef("hidden");
3861 case VisibilityAttr::VisibilityType::Protected:
3862 return cxstring::createRef("protected");
3863 }
3864 llvm_unreachable("unknown visibility type");
3865 }
3866
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003867 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003868}
3869
3870CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3871 unsigned pieceIndex,
3872 unsigned options) {
3873 if (clang_Cursor_isNull(C))
3874 return clang_getNullRange();
3875
3876 ASTContext &Ctx = getCursorContext(C);
3877
3878 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003879 const Stmt *S = getCursorStmt(C);
3880 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003881 if (pieceIndex > 0)
3882 return clang_getNullRange();
3883 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3884 }
3885
3886 return clang_getNullRange();
3887 }
3888
3889 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003890 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003891 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3892 if (pieceIndex >= ME->getNumSelectorLocs())
3893 return clang_getNullRange();
3894 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3895 }
3896 }
3897
3898 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3899 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003900 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003901 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3902 if (pieceIndex >= MD->getNumSelectorLocs())
3903 return clang_getNullRange();
3904 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3905 }
3906 }
3907
3908 if (C.kind == CXCursor_ObjCCategoryDecl ||
3909 C.kind == CXCursor_ObjCCategoryImplDecl) {
3910 if (pieceIndex > 0)
3911 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003912 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003913 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3914 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003915 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003916 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3917 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3918 }
3919
3920 if (C.kind == CXCursor_ModuleImportDecl) {
3921 if (pieceIndex > 0)
3922 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003923 if (const ImportDecl *ImportD =
3924 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003925 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3926 if (!Locs.empty())
3927 return cxloc::translateSourceRange(Ctx,
3928 SourceRange(Locs.front(), Locs.back()));
3929 }
3930 return clang_getNullRange();
3931 }
3932
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00003933 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
3934 C.kind == CXCursor_ConversionFunction) {
3935 if (pieceIndex > 0)
3936 return clang_getNullRange();
3937 if (const FunctionDecl *FD =
3938 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
3939 DeclarationNameInfo FunctionName = FD->getNameInfo();
3940 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
3941 }
3942 return clang_getNullRange();
3943 }
3944
Guy Benyei11169dd2012-12-18 14:30:41 +00003945 // FIXME: A CXCursor_InclusionDirective should give the location of the
3946 // filename, but we don't keep track of this.
3947
3948 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3949 // but we don't keep track of this.
3950
3951 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3952 // but we don't keep track of this.
3953
3954 // Default handling, give the location of the cursor.
3955
3956 if (pieceIndex > 0)
3957 return clang_getNullRange();
3958
3959 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3960 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3961 return cxloc::translateSourceRange(Ctx, Loc);
3962}
3963
Eli Bendersky44a206f2014-07-31 18:04:56 +00003964CXString clang_Cursor_getMangling(CXCursor C) {
3965 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
3966 return cxstring::createEmpty();
3967
Eli Bendersky44a206f2014-07-31 18:04:56 +00003968 // Mangling only works for functions and variables.
Eli Bendersky79759592014-08-01 15:01:10 +00003969 const Decl *D = getCursorDecl(C);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003970 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
3971 return cxstring::createEmpty();
3972
Eli Bendersky79759592014-08-01 15:01:10 +00003973 // First apply frontend mangling.
Eli Bendersky44a206f2014-07-31 18:04:56 +00003974 const NamedDecl *ND = cast<NamedDecl>(D);
Eli Bendersky79759592014-08-01 15:01:10 +00003975 ASTContext &Ctx = ND->getASTContext();
3976 std::unique_ptr<MangleContext> MC(Ctx.createMangleContext());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003977
Eli Bendersky79759592014-08-01 15:01:10 +00003978 std::string FrontendBuf;
3979 llvm::raw_string_ostream FrontendBufOS(FrontendBuf);
Ehsan Akhgarif8d44de2015-10-08 00:01:20 +00003980 if (MC->shouldMangleDeclName(ND)) {
3981 MC->mangleName(ND, FrontendBufOS);
3982 } else {
3983 ND->printName(FrontendBufOS);
3984 }
Eli Bendersky44a206f2014-07-31 18:04:56 +00003985
Eli Bendersky79759592014-08-01 15:01:10 +00003986 // Now apply backend mangling.
3987 std::unique_ptr<llvm::DataLayout> DL(
Eric Christopher964a5f32015-08-05 23:48:05 +00003988 new llvm::DataLayout(Ctx.getTargetInfo().getDataLayoutString()));
Eli Bendersky79759592014-08-01 15:01:10 +00003989
3990 std::string FinalBuf;
3991 llvm::raw_string_ostream FinalBufOS(FinalBuf);
Rafael Espindolab633d202015-06-23 13:59:36 +00003992 llvm::Mangler::getNameWithPrefix(FinalBufOS, llvm::Twine(FrontendBufOS.str()),
3993 *DL);
Eli Bendersky79759592014-08-01 15:01:10 +00003994
3995 return cxstring::createDup(FinalBufOS.str());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003996}
3997
Saleem Abdulrasool60034432015-11-12 03:57:22 +00003998CXStringSet *clang_Cursor_getCXXManglings(CXCursor C) {
3999 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
4000 return nullptr;
4001
4002 const Decl *D = getCursorDecl(C);
4003 if (!(isa<CXXRecordDecl>(D) || isa<CXXMethodDecl>(D)))
4004 return nullptr;
4005
4006 const NamedDecl *ND = cast<NamedDecl>(D);
4007
4008 ASTContext &Ctx = ND->getASTContext();
4009 std::unique_ptr<MangleContext> M(Ctx.createMangleContext());
4010 std::unique_ptr<llvm::DataLayout> DL(
4011 new llvm::DataLayout(Ctx.getTargetInfo().getDataLayoutString()));
4012
4013 std::vector<std::string> Manglings;
4014
4015 auto hasDefaultCXXMethodCC = [](ASTContext &C, const CXXMethodDecl *MD) {
4016 auto DefaultCC = C.getDefaultCallingConvention(/*IsVariadic=*/false,
4017 /*IsCSSMethod=*/true);
4018 auto CC = MD->getType()->getAs<FunctionProtoType>()->getCallConv();
4019 return CC == DefaultCC;
4020 };
4021
4022 if (const auto *CD = dyn_cast_or_null<CXXConstructorDecl>(ND)) {
4023 Manglings.emplace_back(getMangledStructor(M, DL, CD, Ctor_Base));
4024
4025 if (Ctx.getTargetInfo().getCXXABI().isItaniumFamily())
4026 if (!CD->getParent()->isAbstract())
4027 Manglings.emplace_back(getMangledStructor(M, DL, CD, Ctor_Complete));
4028
4029 if (Ctx.getTargetInfo().getCXXABI().isMicrosoft())
4030 if (CD->hasAttr<DLLExportAttr>() && CD->isDefaultConstructor())
4031 if (!(hasDefaultCXXMethodCC(Ctx, CD) && CD->getNumParams() == 0))
4032 Manglings.emplace_back(getMangledStructor(M, DL, CD,
4033 Ctor_DefaultClosure));
4034 } else if (const auto *DD = dyn_cast_or_null<CXXDestructorDecl>(ND)) {
4035 Manglings.emplace_back(getMangledStructor(M, DL, DD, Dtor_Base));
4036 if (Ctx.getTargetInfo().getCXXABI().isItaniumFamily()) {
4037 Manglings.emplace_back(getMangledStructor(M, DL, DD, Dtor_Complete));
Saleem Abdulrasoold5af8ae2015-12-10 06:30:23 +00004038 if (DD->isVirtual())
Saleem Abdulrasool60034432015-11-12 03:57:22 +00004039 Manglings.emplace_back(getMangledStructor(M, DL, DD, Dtor_Deleting));
4040 }
4041 }
4042
4043 return cxstring::createSet(Manglings);
4044}
4045
Guy Benyei11169dd2012-12-18 14:30:41 +00004046CXString clang_getCursorDisplayName(CXCursor C) {
4047 if (!clang_isDeclaration(C.kind))
4048 return clang_getCursorSpelling(C);
4049
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004050 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004051 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004052 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004053
4054 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004055 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004056 D = FunTmpl->getTemplatedDecl();
4057
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004058 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004059 SmallString<64> Str;
4060 llvm::raw_svector_ostream OS(Str);
4061 OS << *Function;
4062 if (Function->getPrimaryTemplate())
4063 OS << "<>";
4064 OS << "(";
4065 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
4066 if (I)
4067 OS << ", ";
4068 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
4069 }
4070
4071 if (Function->isVariadic()) {
4072 if (Function->getNumParams())
4073 OS << ", ";
4074 OS << "...";
4075 }
4076 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004077 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004078 }
4079
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004080 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004081 SmallString<64> Str;
4082 llvm::raw_svector_ostream OS(Str);
4083 OS << *ClassTemplate;
4084 OS << "<";
4085 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
4086 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
4087 if (I)
4088 OS << ", ";
4089
4090 NamedDecl *Param = Params->getParam(I);
4091 if (Param->getIdentifier()) {
4092 OS << Param->getIdentifier()->getName();
4093 continue;
4094 }
4095
4096 // There is no parameter name, which makes this tricky. Try to come up
4097 // with something useful that isn't too long.
4098 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
4099 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
4100 else if (NonTypeTemplateParmDecl *NTTP
4101 = dyn_cast<NonTypeTemplateParmDecl>(Param))
4102 OS << NTTP->getType().getAsString(Policy);
4103 else
4104 OS << "template<...> class";
4105 }
4106
4107 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004108 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004109 }
4110
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004111 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00004112 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
4113 // If the type was explicitly written, use that.
4114 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004115 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00004116
Benjamin Kramer9170e912013-02-22 15:46:01 +00004117 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00004118 llvm::raw_svector_ostream OS(Str);
4119 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00004120 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00004121 ClassSpec->getTemplateArgs().data(),
4122 ClassSpec->getTemplateArgs().size(),
4123 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004124 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004125 }
4126
4127 return clang_getCursorSpelling(C);
4128}
4129
4130CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
4131 switch (Kind) {
4132 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004133 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004134 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004135 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004136 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004137 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004138 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004139 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004140 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004141 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004142 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004143 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004144 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004145 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004146 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004147 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004148 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004149 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004150 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004151 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004152 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004153 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004154 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004155 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004156 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004157 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004158 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004159 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004160 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004161 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004162 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004163 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004164 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004165 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004166 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004167 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004168 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004169 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004170 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004171 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00004172 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004173 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004174 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004175 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004176 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004177 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004178 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004179 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004180 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004181 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004182 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004183 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004184 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004185 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004186 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004187 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004188 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004189 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004190 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004191 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004192 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004193 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004194 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004195 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004196 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004197 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004198 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004199 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004200 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004201 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004202 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004203 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004204 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004205 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004206 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004207 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004208 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004209 return cxstring::createRef("ArraySubscriptExpr");
Alexey Bataev1a3320e2015-08-25 14:24:04 +00004210 case CXCursor_OMPArraySectionExpr:
4211 return cxstring::createRef("OMPArraySectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004212 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004213 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004214 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004215 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004216 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004217 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004218 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004219 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004220 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004221 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004222 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004223 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004224 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004225 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004226 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004227 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004228 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004229 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004230 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004231 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004232 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004233 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004234 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004235 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004236 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004237 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004238 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004239 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004240 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004241 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004242 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004243 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004244 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004245 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004246 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004247 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004248 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004249 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004250 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004251 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004252 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004253 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004254 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004255 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004256 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004257 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004258 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004259 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004260 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004261 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00004262 case CXCursor_ObjCSelfExpr:
4263 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004264 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004265 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004266 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004267 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004268 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004269 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004270 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004271 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004272 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004273 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004274 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004275 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004276 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004277 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004278 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004279 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004280 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004281 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004282 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004283 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004284 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004285 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004286 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004287 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004288 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004289 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004290 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004291 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004292 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004293 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004294 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004295 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004296 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004297 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004298 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004299 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004300 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004301 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004302 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004303 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004304 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004305 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004306 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004307 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004308 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004309 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004310 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004311 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004312 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004313 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004314 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004315 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004316 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004317 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004318 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004319 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004320 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004321 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004322 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004323 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004324 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004325 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004326 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004327 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004328 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004329 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004330 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004331 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004332 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004333 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004334 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004335 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004336 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004337 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004338 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004339 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004340 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004341 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004342 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004343 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004344 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004345 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004346 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004347 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004348 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004349 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004350 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004351 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00004352 case CXCursor_SEHLeaveStmt:
4353 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004354 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004355 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004356 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004357 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00004358 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004359 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00004360 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004361 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00004362 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004363 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00004364 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004365 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00004366 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004367 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004368 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004369 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004370 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004371 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004372 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004373 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004374 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004375 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004376 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004377 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004378 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004379 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004380 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004381 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004382 case CXCursor_PackedAttr:
4383 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00004384 case CXCursor_PureAttr:
4385 return cxstring::createRef("attribute(pure)");
4386 case CXCursor_ConstAttr:
4387 return cxstring::createRef("attribute(const)");
4388 case CXCursor_NoDuplicateAttr:
4389 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00004390 case CXCursor_CUDAConstantAttr:
4391 return cxstring::createRef("attribute(constant)");
4392 case CXCursor_CUDADeviceAttr:
4393 return cxstring::createRef("attribute(device)");
4394 case CXCursor_CUDAGlobalAttr:
4395 return cxstring::createRef("attribute(global)");
4396 case CXCursor_CUDAHostAttr:
4397 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00004398 case CXCursor_CUDASharedAttr:
4399 return cxstring::createRef("attribute(shared)");
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00004400 case CXCursor_VisibilityAttr:
4401 return cxstring::createRef("attribute(visibility)");
Saleem Abdulrasool8aa0b802015-12-10 18:45:18 +00004402 case CXCursor_DLLExport:
4403 return cxstring::createRef("attribute(dllexport)");
4404 case CXCursor_DLLImport:
4405 return cxstring::createRef("attribute(dllimport)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004406 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004407 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004408 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004409 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00004410 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004411 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004412 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004413 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004414 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004415 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00004416 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004417 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00004418 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004419 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004420 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004421 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004422 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004423 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004424 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004425 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004426 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004427 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004428 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004429 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004430 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004431 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004432 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004433 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004434 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004435 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004436 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004437 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004438 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004439 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004440 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004441 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004442 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004443 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004444 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004445 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004446 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004447 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004448 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004449 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004450 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004451 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004452 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004453 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004454 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004455 return cxstring::createRef("OMPParallelDirective");
4456 case CXCursor_OMPSimdDirective:
4457 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004458 case CXCursor_OMPForDirective:
4459 return cxstring::createRef("OMPForDirective");
Alexander Musmanf82886e2014-09-18 05:12:34 +00004460 case CXCursor_OMPForSimdDirective:
4461 return cxstring::createRef("OMPForSimdDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004462 case CXCursor_OMPSectionsDirective:
4463 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004464 case CXCursor_OMPSectionDirective:
4465 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004466 case CXCursor_OMPSingleDirective:
4467 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004468 case CXCursor_OMPMasterDirective:
4469 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004470 case CXCursor_OMPCriticalDirective:
4471 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004472 case CXCursor_OMPParallelForDirective:
4473 return cxstring::createRef("OMPParallelForDirective");
Alexander Musmane4e893b2014-09-23 09:33:00 +00004474 case CXCursor_OMPParallelForSimdDirective:
4475 return cxstring::createRef("OMPParallelForSimdDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004476 case CXCursor_OMPParallelSectionsDirective:
4477 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004478 case CXCursor_OMPTaskDirective:
4479 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004480 case CXCursor_OMPTaskyieldDirective:
4481 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004482 case CXCursor_OMPBarrierDirective:
4483 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004484 case CXCursor_OMPTaskwaitDirective:
4485 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00004486 case CXCursor_OMPTaskgroupDirective:
4487 return cxstring::createRef("OMPTaskgroupDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00004488 case CXCursor_OMPFlushDirective:
4489 return cxstring::createRef("OMPFlushDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004490 case CXCursor_OMPOrderedDirective:
4491 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00004492 case CXCursor_OMPAtomicDirective:
4493 return cxstring::createRef("OMPAtomicDirective");
Alexey Bataev0bd520b2014-09-19 08:19:49 +00004494 case CXCursor_OMPTargetDirective:
4495 return cxstring::createRef("OMPTargetDirective");
Michael Wong65f367f2015-07-21 13:44:28 +00004496 case CXCursor_OMPTargetDataDirective:
4497 return cxstring::createRef("OMPTargetDataDirective");
Alexey Bataev13314bf2014-10-09 04:18:56 +00004498 case CXCursor_OMPTeamsDirective:
4499 return cxstring::createRef("OMPTeamsDirective");
Alexey Bataev6d4ed052015-07-01 06:57:41 +00004500 case CXCursor_OMPCancellationPointDirective:
4501 return cxstring::createRef("OMPCancellationPointDirective");
Alexey Bataev80909872015-07-02 11:25:17 +00004502 case CXCursor_OMPCancelDirective:
4503 return cxstring::createRef("OMPCancelDirective");
Alexey Bataev49f6e782015-12-01 04:18:41 +00004504 case CXCursor_OMPTaskLoopDirective:
4505 return cxstring::createRef("OMPTaskLoopDirective");
Alexey Bataev0a6ed842015-12-03 09:40:15 +00004506 case CXCursor_OMPTaskLoopSimdDirective:
4507 return cxstring::createRef("OMPTaskLoopSimdDirective");
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00004508 case CXCursor_OMPDistributeDirective:
4509 return cxstring::createRef("OMPDistributeDirective");
Francisco Lopes da Silva975a9f62015-01-21 16:24:11 +00004510 case CXCursor_OverloadCandidate:
4511 return cxstring::createRef("OverloadCandidate");
Sergey Kalinichev8f3b1872015-11-15 13:48:32 +00004512 case CXCursor_TypeAliasTemplateDecl:
4513 return cxstring::createRef("TypeAliasTemplateDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004514 }
4515
4516 llvm_unreachable("Unhandled CXCursorKind");
4517}
4518
4519struct GetCursorData {
4520 SourceLocation TokenBeginLoc;
4521 bool PointsAtMacroArgExpansion;
4522 bool VisitedObjCPropertyImplDecl;
4523 SourceLocation VisitedDeclaratorDeclStartLoc;
4524 CXCursor &BestCursor;
4525
4526 GetCursorData(SourceManager &SM,
4527 SourceLocation tokenBegin, CXCursor &outputCursor)
4528 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4529 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4530 VisitedObjCPropertyImplDecl = false;
4531 }
4532};
4533
4534static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4535 CXCursor parent,
4536 CXClientData client_data) {
4537 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4538 CXCursor *BestCursor = &Data->BestCursor;
4539
4540 // If we point inside a macro argument we should provide info of what the
4541 // token is so use the actual cursor, don't replace it with a macro expansion
4542 // cursor.
4543 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4544 return CXChildVisit_Recurse;
4545
4546 if (clang_isDeclaration(cursor.kind)) {
4547 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004548 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004549 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4550 if (MD->isImplicit())
4551 return CXChildVisit_Break;
4552
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004553 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004554 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4555 // Check that when we have multiple @class references in the same line,
4556 // that later ones do not override the previous ones.
4557 // If we have:
4558 // @class Foo, Bar;
4559 // source ranges for both start at '@', so 'Bar' will end up overriding
4560 // 'Foo' even though the cursor location was at 'Foo'.
4561 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4562 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004563 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004564 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4565 if (PrevID != ID &&
4566 !PrevID->isThisDeclarationADefinition() &&
4567 !ID->isThisDeclarationADefinition())
4568 return CXChildVisit_Break;
4569 }
4570
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004571 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004572 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4573 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4574 // Check that when we have multiple declarators in the same line,
4575 // that later ones do not override the previous ones.
4576 // If we have:
4577 // int Foo, Bar;
4578 // source ranges for both start at 'int', so 'Bar' will end up overriding
4579 // 'Foo' even though the cursor location was at 'Foo'.
4580 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4581 return CXChildVisit_Break;
4582 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4583
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004584 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004585 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4586 (void)PropImp;
4587 // Check that when we have multiple @synthesize in the same line,
4588 // that later ones do not override the previous ones.
4589 // If we have:
4590 // @synthesize Foo, Bar;
4591 // source ranges for both start at '@', so 'Bar' will end up overriding
4592 // 'Foo' even though the cursor location was at 'Foo'.
4593 if (Data->VisitedObjCPropertyImplDecl)
4594 return CXChildVisit_Break;
4595 Data->VisitedObjCPropertyImplDecl = true;
4596 }
4597 }
4598
4599 if (clang_isExpression(cursor.kind) &&
4600 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004601 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004602 // Avoid having the cursor of an expression replace the declaration cursor
4603 // when the expression source range overlaps the declaration range.
4604 // This can happen for C++ constructor expressions whose range generally
4605 // include the variable declaration, e.g.:
4606 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4607 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4608 D->getLocation() == Data->TokenBeginLoc)
4609 return CXChildVisit_Break;
4610 }
4611 }
4612
4613 // If our current best cursor is the construction of a temporary object,
4614 // don't replace that cursor with a type reference, because we want
4615 // clang_getCursor() to point at the constructor.
4616 if (clang_isExpression(BestCursor->kind) &&
4617 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4618 cursor.kind == CXCursor_TypeRef) {
4619 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4620 // as having the actual point on the type reference.
4621 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4622 return CXChildVisit_Recurse;
4623 }
Douglas Gregore9d95f12015-07-07 03:57:35 +00004624
4625 // If we already have an Objective-C superclass reference, don't
4626 // update it further.
4627 if (BestCursor->kind == CXCursor_ObjCSuperClassRef)
4628 return CXChildVisit_Break;
4629
Guy Benyei11169dd2012-12-18 14:30:41 +00004630 *BestCursor = cursor;
4631 return CXChildVisit_Recurse;
4632}
4633
4634CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004635 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004636 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004637 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004638 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004639
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004640 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004641 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4642
4643 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4644 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4645
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004646 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004647 CXFile SearchFile;
4648 unsigned SearchLine, SearchColumn;
4649 CXFile ResultFile;
4650 unsigned ResultLine, ResultColumn;
4651 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4652 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4653 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004654
4655 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4656 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004657 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004658 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004659 SearchFileName = clang_getFileName(SearchFile);
4660 ResultFileName = clang_getFileName(ResultFile);
4661 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4662 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004663 *Log << llvm::format("(%s:%d:%d) = %s",
4664 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4665 clang_getCString(KindSpelling))
4666 << llvm::format("(%s:%d:%d):%s%s",
4667 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4668 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004669 clang_disposeString(SearchFileName);
4670 clang_disposeString(ResultFileName);
4671 clang_disposeString(KindSpelling);
4672 clang_disposeString(USR);
4673
4674 CXCursor Definition = clang_getCursorDefinition(Result);
4675 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4676 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4677 CXString DefinitionKindSpelling
4678 = clang_getCursorKindSpelling(Definition.kind);
4679 CXFile DefinitionFile;
4680 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004681 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004682 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004683 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004684 *Log << llvm::format(" -> %s(%s:%d:%d)",
4685 clang_getCString(DefinitionKindSpelling),
4686 clang_getCString(DefinitionFileName),
4687 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004688 clang_disposeString(DefinitionFileName);
4689 clang_disposeString(DefinitionKindSpelling);
4690 }
4691 }
4692
4693 return Result;
4694}
4695
4696CXCursor clang_getNullCursor(void) {
4697 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4698}
4699
4700unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004701 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4702 // can't set consistently. For example, when visiting a DeclStmt we will set
4703 // it but we don't set it on the result of clang_getCursorDefinition for
4704 // a reference of the same declaration.
4705 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4706 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4707 // to provide that kind of info.
4708 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004709 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004710 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004711 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004712
Guy Benyei11169dd2012-12-18 14:30:41 +00004713 return X == Y;
4714}
4715
4716unsigned clang_hashCursor(CXCursor C) {
4717 unsigned Index = 0;
4718 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4719 Index = 1;
4720
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004721 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004722 std::make_pair(C.kind, C.data[Index]));
4723}
4724
4725unsigned clang_isInvalid(enum CXCursorKind K) {
4726 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4727}
4728
4729unsigned clang_isDeclaration(enum CXCursorKind K) {
4730 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4731 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4732}
4733
4734unsigned clang_isReference(enum CXCursorKind K) {
4735 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4736}
4737
4738unsigned clang_isExpression(enum CXCursorKind K) {
4739 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4740}
4741
4742unsigned clang_isStatement(enum CXCursorKind K) {
4743 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4744}
4745
4746unsigned clang_isAttribute(enum CXCursorKind K) {
4747 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4748}
4749
4750unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4751 return K == CXCursor_TranslationUnit;
4752}
4753
4754unsigned clang_isPreprocessing(enum CXCursorKind K) {
4755 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4756}
4757
4758unsigned clang_isUnexposed(enum CXCursorKind K) {
4759 switch (K) {
4760 case CXCursor_UnexposedDecl:
4761 case CXCursor_UnexposedExpr:
4762 case CXCursor_UnexposedStmt:
4763 case CXCursor_UnexposedAttr:
4764 return true;
4765 default:
4766 return false;
4767 }
4768}
4769
4770CXCursorKind clang_getCursorKind(CXCursor C) {
4771 return C.kind;
4772}
4773
4774CXSourceLocation clang_getCursorLocation(CXCursor C) {
4775 if (clang_isReference(C.kind)) {
4776 switch (C.kind) {
4777 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004778 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004779 = getCursorObjCSuperClassRef(C);
4780 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4781 }
4782
4783 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004784 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004785 = getCursorObjCProtocolRef(C);
4786 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4787 }
4788
4789 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004790 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004791 = getCursorObjCClassRef(C);
4792 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4793 }
4794
4795 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004796 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004797 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4798 }
4799
4800 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004801 std::pair<const TemplateDecl *, SourceLocation> P =
4802 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004803 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4804 }
4805
4806 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004807 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004808 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4809 }
4810
4811 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004812 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004813 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4814 }
4815
4816 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004817 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004818 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4819 }
4820
4821 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004822 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004823 if (!BaseSpec)
4824 return clang_getNullLocation();
4825
4826 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4827 return cxloc::translateSourceLocation(getCursorContext(C),
4828 TSInfo->getTypeLoc().getBeginLoc());
4829
4830 return cxloc::translateSourceLocation(getCursorContext(C),
4831 BaseSpec->getLocStart());
4832 }
4833
4834 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004835 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004836 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4837 }
4838
4839 case CXCursor_OverloadedDeclRef:
4840 return cxloc::translateSourceLocation(getCursorContext(C),
4841 getCursorOverloadedDeclRef(C).second);
4842
4843 default:
4844 // FIXME: Need a way to enumerate all non-reference cases.
4845 llvm_unreachable("Missed a reference kind");
4846 }
4847 }
4848
4849 if (clang_isExpression(C.kind))
4850 return cxloc::translateSourceLocation(getCursorContext(C),
4851 getLocationFromExpr(getCursorExpr(C)));
4852
4853 if (clang_isStatement(C.kind))
4854 return cxloc::translateSourceLocation(getCursorContext(C),
4855 getCursorStmt(C)->getLocStart());
4856
4857 if (C.kind == CXCursor_PreprocessingDirective) {
4858 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4859 return cxloc::translateSourceLocation(getCursorContext(C), L);
4860 }
4861
4862 if (C.kind == CXCursor_MacroExpansion) {
4863 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004864 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004865 return cxloc::translateSourceLocation(getCursorContext(C), L);
4866 }
4867
4868 if (C.kind == CXCursor_MacroDefinition) {
4869 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4870 return cxloc::translateSourceLocation(getCursorContext(C), L);
4871 }
4872
4873 if (C.kind == CXCursor_InclusionDirective) {
4874 SourceLocation L
4875 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4876 return cxloc::translateSourceLocation(getCursorContext(C), L);
4877 }
4878
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004879 if (clang_isAttribute(C.kind)) {
4880 SourceLocation L
4881 = cxcursor::getCursorAttr(C)->getLocation();
4882 return cxloc::translateSourceLocation(getCursorContext(C), L);
4883 }
4884
Guy Benyei11169dd2012-12-18 14:30:41 +00004885 if (!clang_isDeclaration(C.kind))
4886 return clang_getNullLocation();
4887
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004888 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004889 if (!D)
4890 return clang_getNullLocation();
4891
4892 SourceLocation Loc = D->getLocation();
4893 // FIXME: Multiple variables declared in a single declaration
4894 // currently lack the information needed to correctly determine their
4895 // ranges when accounting for the type-specifier. We use context
4896 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4897 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004898 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004899 if (!cxcursor::isFirstInDeclGroup(C))
4900 Loc = VD->getLocation();
4901 }
4902
4903 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004904 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004905 Loc = MD->getSelectorStartLoc();
4906
4907 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4908}
4909
4910} // end extern "C"
4911
4912CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4913 assert(TU);
4914
4915 // Guard against an invalid SourceLocation, or we may assert in one
4916 // of the following calls.
4917 if (SLoc.isInvalid())
4918 return clang_getNullCursor();
4919
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004920 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004921
4922 // Translate the given source location to make it point at the beginning of
4923 // the token under the cursor.
4924 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4925 CXXUnit->getASTContext().getLangOpts());
4926
4927 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4928 if (SLoc.isValid()) {
4929 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4930 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4931 /*VisitPreprocessorLast=*/true,
4932 /*VisitIncludedEntities=*/false,
4933 SourceLocation(SLoc));
4934 CursorVis.visitFileRegion();
4935 }
4936
4937 return Result;
4938}
4939
4940static SourceRange getRawCursorExtent(CXCursor C) {
4941 if (clang_isReference(C.kind)) {
4942 switch (C.kind) {
4943 case CXCursor_ObjCSuperClassRef:
4944 return getCursorObjCSuperClassRef(C).second;
4945
4946 case CXCursor_ObjCProtocolRef:
4947 return getCursorObjCProtocolRef(C).second;
4948
4949 case CXCursor_ObjCClassRef:
4950 return getCursorObjCClassRef(C).second;
4951
4952 case CXCursor_TypeRef:
4953 return getCursorTypeRef(C).second;
4954
4955 case CXCursor_TemplateRef:
4956 return getCursorTemplateRef(C).second;
4957
4958 case CXCursor_NamespaceRef:
4959 return getCursorNamespaceRef(C).second;
4960
4961 case CXCursor_MemberRef:
4962 return getCursorMemberRef(C).second;
4963
4964 case CXCursor_CXXBaseSpecifier:
4965 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4966
4967 case CXCursor_LabelRef:
4968 return getCursorLabelRef(C).second;
4969
4970 case CXCursor_OverloadedDeclRef:
4971 return getCursorOverloadedDeclRef(C).second;
4972
4973 case CXCursor_VariableRef:
4974 return getCursorVariableRef(C).second;
4975
4976 default:
4977 // FIXME: Need a way to enumerate all non-reference cases.
4978 llvm_unreachable("Missed a reference kind");
4979 }
4980 }
4981
4982 if (clang_isExpression(C.kind))
4983 return getCursorExpr(C)->getSourceRange();
4984
4985 if (clang_isStatement(C.kind))
4986 return getCursorStmt(C)->getSourceRange();
4987
4988 if (clang_isAttribute(C.kind))
4989 return getCursorAttr(C)->getRange();
4990
4991 if (C.kind == CXCursor_PreprocessingDirective)
4992 return cxcursor::getCursorPreprocessingDirective(C);
4993
4994 if (C.kind == CXCursor_MacroExpansion) {
4995 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004996 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004997 return TU->mapRangeFromPreamble(Range);
4998 }
4999
5000 if (C.kind == CXCursor_MacroDefinition) {
5001 ASTUnit *TU = getCursorASTUnit(C);
5002 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
5003 return TU->mapRangeFromPreamble(Range);
5004 }
5005
5006 if (C.kind == CXCursor_InclusionDirective) {
5007 ASTUnit *TU = getCursorASTUnit(C);
5008 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
5009 return TU->mapRangeFromPreamble(Range);
5010 }
5011
5012 if (C.kind == CXCursor_TranslationUnit) {
5013 ASTUnit *TU = getCursorASTUnit(C);
5014 FileID MainID = TU->getSourceManager().getMainFileID();
5015 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
5016 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
5017 return SourceRange(Start, End);
5018 }
5019
5020 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005021 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005022 if (!D)
5023 return SourceRange();
5024
5025 SourceRange R = D->getSourceRange();
5026 // FIXME: Multiple variables declared in a single declaration
5027 // currently lack the information needed to correctly determine their
5028 // ranges when accounting for the type-specifier. We use context
5029 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
5030 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005031 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005032 if (!cxcursor::isFirstInDeclGroup(C))
5033 R.setBegin(VD->getLocation());
5034 }
5035 return R;
5036 }
5037 return SourceRange();
5038}
5039
5040/// \brief Retrieves the "raw" cursor extent, which is then extended to include
5041/// the decl-specifier-seq for declarations.
5042static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
5043 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005044 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005045 if (!D)
5046 return SourceRange();
5047
5048 SourceRange R = D->getSourceRange();
5049
5050 // Adjust the start of the location for declarations preceded by
5051 // declaration specifiers.
5052 SourceLocation StartLoc;
5053 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
5054 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
5055 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005056 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005057 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
5058 StartLoc = TI->getTypeLoc().getLocStart();
5059 }
5060
5061 if (StartLoc.isValid() && R.getBegin().isValid() &&
5062 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
5063 R.setBegin(StartLoc);
5064
5065 // FIXME: Multiple variables declared in a single declaration
5066 // currently lack the information needed to correctly determine their
5067 // ranges when accounting for the type-specifier. We use context
5068 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
5069 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005070 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005071 if (!cxcursor::isFirstInDeclGroup(C))
5072 R.setBegin(VD->getLocation());
5073 }
5074
5075 return R;
5076 }
5077
5078 return getRawCursorExtent(C);
5079}
5080
5081extern "C" {
5082
5083CXSourceRange clang_getCursorExtent(CXCursor C) {
5084 SourceRange R = getRawCursorExtent(C);
5085 if (R.isInvalid())
5086 return clang_getNullRange();
5087
5088 return cxloc::translateSourceRange(getCursorContext(C), R);
5089}
5090
5091CXCursor clang_getCursorReferenced(CXCursor C) {
5092 if (clang_isInvalid(C.kind))
5093 return clang_getNullCursor();
5094
5095 CXTranslationUnit tu = getCursorTU(C);
5096 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005097 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005098 if (!D)
5099 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005100 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005101 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005102 if (const ObjCPropertyImplDecl *PropImpl =
5103 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005104 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
5105 return MakeCXCursor(Property, tu);
5106
5107 return C;
5108 }
5109
5110 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005111 const Expr *E = getCursorExpr(C);
5112 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00005113 if (D) {
5114 CXCursor declCursor = MakeCXCursor(D, tu);
5115 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
5116 declCursor);
5117 return declCursor;
5118 }
5119
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005120 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00005121 return MakeCursorOverloadedDeclRef(Ovl, tu);
5122
5123 return clang_getNullCursor();
5124 }
5125
5126 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005127 const Stmt *S = getCursorStmt(C);
5128 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00005129 if (LabelDecl *label = Goto->getLabel())
5130 if (LabelStmt *labelS = label->getStmt())
5131 return MakeCXCursor(labelS, getCursorDecl(C), tu);
5132
5133 return clang_getNullCursor();
5134 }
Richard Smith66a81862015-05-04 02:25:31 +00005135
Guy Benyei11169dd2012-12-18 14:30:41 +00005136 if (C.kind == CXCursor_MacroExpansion) {
Richard Smith66a81862015-05-04 02:25:31 +00005137 if (const MacroDefinitionRecord *Def =
5138 getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005139 return MakeMacroDefinitionCursor(Def, tu);
5140 }
5141
5142 if (!clang_isReference(C.kind))
5143 return clang_getNullCursor();
5144
5145 switch (C.kind) {
5146 case CXCursor_ObjCSuperClassRef:
5147 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
5148
5149 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005150 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
5151 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005152 return MakeCXCursor(Def, tu);
5153
5154 return MakeCXCursor(Prot, tu);
5155 }
5156
5157 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005158 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
5159 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005160 return MakeCXCursor(Def, tu);
5161
5162 return MakeCXCursor(Class, tu);
5163 }
5164
5165 case CXCursor_TypeRef:
5166 return MakeCXCursor(getCursorTypeRef(C).first, tu );
5167
5168 case CXCursor_TemplateRef:
5169 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
5170
5171 case CXCursor_NamespaceRef:
5172 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
5173
5174 case CXCursor_MemberRef:
5175 return MakeCXCursor(getCursorMemberRef(C).first, tu );
5176
5177 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005178 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005179 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
5180 tu ));
5181 }
5182
5183 case CXCursor_LabelRef:
5184 // FIXME: We end up faking the "parent" declaration here because we
5185 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005186 return MakeCXCursor(getCursorLabelRef(C).first,
5187 cxtu::getASTUnit(tu)->getASTContext()
5188 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00005189 tu);
5190
5191 case CXCursor_OverloadedDeclRef:
5192 return C;
5193
5194 case CXCursor_VariableRef:
5195 return MakeCXCursor(getCursorVariableRef(C).first, tu);
5196
5197 default:
5198 // We would prefer to enumerate all non-reference cursor kinds here.
5199 llvm_unreachable("Unhandled reference cursor kind");
5200 }
5201}
5202
5203CXCursor clang_getCursorDefinition(CXCursor C) {
5204 if (clang_isInvalid(C.kind))
5205 return clang_getNullCursor();
5206
5207 CXTranslationUnit TU = getCursorTU(C);
5208
5209 bool WasReference = false;
5210 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
5211 C = clang_getCursorReferenced(C);
5212 WasReference = true;
5213 }
5214
5215 if (C.kind == CXCursor_MacroExpansion)
5216 return clang_getCursorReferenced(C);
5217
5218 if (!clang_isDeclaration(C.kind))
5219 return clang_getNullCursor();
5220
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005221 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005222 if (!D)
5223 return clang_getNullCursor();
5224
5225 switch (D->getKind()) {
5226 // Declaration kinds that don't really separate the notions of
5227 // declaration and definition.
5228 case Decl::Namespace:
5229 case Decl::Typedef:
5230 case Decl::TypeAlias:
5231 case Decl::TypeAliasTemplate:
5232 case Decl::TemplateTypeParm:
5233 case Decl::EnumConstant:
5234 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00005235 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005236 case Decl::IndirectField:
5237 case Decl::ObjCIvar:
5238 case Decl::ObjCAtDefsField:
5239 case Decl::ImplicitParam:
5240 case Decl::ParmVar:
5241 case Decl::NonTypeTemplateParm:
5242 case Decl::TemplateTemplateParm:
5243 case Decl::ObjCCategoryImpl:
5244 case Decl::ObjCImplementation:
5245 case Decl::AccessSpec:
5246 case Decl::LinkageSpec:
5247 case Decl::ObjCPropertyImpl:
5248 case Decl::FileScopeAsm:
5249 case Decl::StaticAssert:
5250 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00005251 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00005252 case Decl::Label: // FIXME: Is this right??
5253 case Decl::ClassScopeFunctionSpecialization:
5254 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00005255 case Decl::OMPThreadPrivate:
Douglas Gregor85f3f952015-07-07 03:57:15 +00005256 case Decl::ObjCTypeParam:
David Majnemerd9b1a4f2015-11-04 03:40:30 +00005257 case Decl::BuiltinTemplate:
Guy Benyei11169dd2012-12-18 14:30:41 +00005258 return C;
5259
5260 // Declaration kinds that don't make any sense here, but are
5261 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00005262 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005263 case Decl::TranslationUnit:
Richard Smithf19e1272015-03-07 00:04:49 +00005264 case Decl::ExternCContext:
Guy Benyei11169dd2012-12-18 14:30:41 +00005265 break;
5266
5267 // Declaration kinds for which the definition is not resolvable.
5268 case Decl::UnresolvedUsingTypename:
5269 case Decl::UnresolvedUsingValue:
5270 break;
5271
5272 case Decl::UsingDirective:
5273 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
5274 TU);
5275
5276 case Decl::NamespaceAlias:
5277 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
5278
5279 case Decl::Enum:
5280 case Decl::Record:
5281 case Decl::CXXRecord:
5282 case Decl::ClassTemplateSpecialization:
5283 case Decl::ClassTemplatePartialSpecialization:
5284 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
5285 return MakeCXCursor(Def, TU);
5286 return clang_getNullCursor();
5287
5288 case Decl::Function:
5289 case Decl::CXXMethod:
5290 case Decl::CXXConstructor:
5291 case Decl::CXXDestructor:
5292 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00005293 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005294 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00005295 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005296 return clang_getNullCursor();
5297 }
5298
Larisse Voufo39a1e502013-08-06 01:03:05 +00005299 case Decl::Var:
5300 case Decl::VarTemplateSpecialization:
5301 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00005302 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005303 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005304 return MakeCXCursor(Def, TU);
5305 return clang_getNullCursor();
5306 }
5307
5308 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00005309 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005310 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
5311 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
5312 return clang_getNullCursor();
5313 }
5314
5315 case Decl::ClassTemplate: {
5316 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
5317 ->getDefinition())
5318 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
5319 TU);
5320 return clang_getNullCursor();
5321 }
5322
Larisse Voufo39a1e502013-08-06 01:03:05 +00005323 case Decl::VarTemplate: {
5324 if (VarDecl *Def =
5325 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
5326 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
5327 return clang_getNullCursor();
5328 }
5329
Guy Benyei11169dd2012-12-18 14:30:41 +00005330 case Decl::Using:
5331 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
5332 D->getLocation(), TU);
5333
5334 case Decl::UsingShadow:
5335 return clang_getCursorDefinition(
5336 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
5337 TU));
5338
5339 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005340 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005341 if (Method->isThisDeclarationADefinition())
5342 return C;
5343
5344 // Dig out the method definition in the associated
5345 // @implementation, if we have it.
5346 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005347 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005348 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
5349 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
5350 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
5351 Method->isInstanceMethod()))
5352 if (Def->isThisDeclarationADefinition())
5353 return MakeCXCursor(Def, TU);
5354
5355 return clang_getNullCursor();
5356 }
5357
5358 case Decl::ObjCCategory:
5359 if (ObjCCategoryImplDecl *Impl
5360 = cast<ObjCCategoryDecl>(D)->getImplementation())
5361 return MakeCXCursor(Impl, TU);
5362 return clang_getNullCursor();
5363
5364 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005365 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005366 return MakeCXCursor(Def, TU);
5367 return clang_getNullCursor();
5368
5369 case Decl::ObjCInterface: {
5370 // There are two notions of a "definition" for an Objective-C
5371 // class: the interface and its implementation. When we resolved a
5372 // reference to an Objective-C class, produce the @interface as
5373 // the definition; when we were provided with the interface,
5374 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005375 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005376 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005377 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005378 return MakeCXCursor(Def, TU);
5379 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
5380 return MakeCXCursor(Impl, TU);
5381 return clang_getNullCursor();
5382 }
5383
5384 case Decl::ObjCProperty:
5385 // FIXME: We don't really know where to find the
5386 // ObjCPropertyImplDecls that implement this property.
5387 return clang_getNullCursor();
5388
5389 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005390 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005391 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005392 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005393 return MakeCXCursor(Def, TU);
5394
5395 return clang_getNullCursor();
5396
5397 case Decl::Friend:
5398 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
5399 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5400 return clang_getNullCursor();
5401
5402 case Decl::FriendTemplate:
5403 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
5404 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5405 return clang_getNullCursor();
5406 }
5407
5408 return clang_getNullCursor();
5409}
5410
5411unsigned clang_isCursorDefinition(CXCursor C) {
5412 if (!clang_isDeclaration(C.kind))
5413 return 0;
5414
5415 return clang_getCursorDefinition(C) == C;
5416}
5417
5418CXCursor clang_getCanonicalCursor(CXCursor C) {
5419 if (!clang_isDeclaration(C.kind))
5420 return C;
5421
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005422 if (const Decl *D = getCursorDecl(C)) {
5423 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005424 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5425 return MakeCXCursor(CatD, getCursorTU(C));
5426
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005427 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5428 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00005429 return MakeCXCursor(IFD, getCursorTU(C));
5430
5431 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5432 }
5433
5434 return C;
5435}
5436
5437int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5438 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5439}
5440
5441unsigned clang_getNumOverloadedDecls(CXCursor C) {
5442 if (C.kind != CXCursor_OverloadedDeclRef)
5443 return 0;
5444
5445 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005446 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005447 return E->getNumDecls();
5448
5449 if (OverloadedTemplateStorage *S
5450 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5451 return S->size();
5452
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005453 const Decl *D = Storage.get<const Decl *>();
5454 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005455 return Using->shadow_size();
5456
5457 return 0;
5458}
5459
5460CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5461 if (cursor.kind != CXCursor_OverloadedDeclRef)
5462 return clang_getNullCursor();
5463
5464 if (index >= clang_getNumOverloadedDecls(cursor))
5465 return clang_getNullCursor();
5466
5467 CXTranslationUnit TU = getCursorTU(cursor);
5468 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005469 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005470 return MakeCXCursor(E->decls_begin()[index], TU);
5471
5472 if (OverloadedTemplateStorage *S
5473 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5474 return MakeCXCursor(S->begin()[index], TU);
5475
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005476 const Decl *D = Storage.get<const Decl *>();
5477 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005478 // FIXME: This is, unfortunately, linear time.
5479 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5480 std::advance(Pos, index);
5481 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5482 }
5483
5484 return clang_getNullCursor();
5485}
5486
5487void clang_getDefinitionSpellingAndExtent(CXCursor C,
5488 const char **startBuf,
5489 const char **endBuf,
5490 unsigned *startLine,
5491 unsigned *startColumn,
5492 unsigned *endLine,
5493 unsigned *endColumn) {
5494 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005495 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005496 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5497
5498 SourceManager &SM = FD->getASTContext().getSourceManager();
5499 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5500 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5501 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5502 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5503 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5504 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5505}
5506
5507
5508CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5509 unsigned PieceIndex) {
5510 RefNamePieces Pieces;
5511
5512 switch (C.kind) {
5513 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005514 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005515 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5516 E->getQualifierLoc().getSourceRange());
5517 break;
5518
5519 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005520 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005521 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
5522 E->getQualifierLoc().getSourceRange(),
5523 E->getOptionalExplicitTemplateArgs());
5524 break;
5525
5526 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005527 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005528 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005529 const Expr *Callee = OCE->getCallee();
5530 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005531 Callee = ICE->getSubExpr();
5532
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005533 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005534 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5535 DRE->getQualifierLoc().getSourceRange());
5536 }
5537 break;
5538
5539 default:
5540 break;
5541 }
5542
5543 if (Pieces.empty()) {
5544 if (PieceIndex == 0)
5545 return clang_getCursorExtent(C);
5546 } else if (PieceIndex < Pieces.size()) {
5547 SourceRange R = Pieces[PieceIndex];
5548 if (R.isValid())
5549 return cxloc::translateSourceRange(getCursorContext(C), R);
5550 }
5551
5552 return clang_getNullRange();
5553}
5554
5555void clang_enableStackTraces(void) {
5556 llvm::sys::PrintStackTraceOnErrorSignal();
5557}
5558
5559void clang_executeOnThread(void (*fn)(void*), void *user_data,
5560 unsigned stack_size) {
5561 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5562}
5563
5564} // end: extern "C"
5565
5566//===----------------------------------------------------------------------===//
5567// Token-based Operations.
5568//===----------------------------------------------------------------------===//
5569
5570/* CXToken layout:
5571 * int_data[0]: a CXTokenKind
5572 * int_data[1]: starting token location
5573 * int_data[2]: token length
5574 * int_data[3]: reserved
5575 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5576 * otherwise unused.
5577 */
5578extern "C" {
5579
5580CXTokenKind clang_getTokenKind(CXToken CXTok) {
5581 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5582}
5583
5584CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5585 switch (clang_getTokenKind(CXTok)) {
5586 case CXToken_Identifier:
5587 case CXToken_Keyword:
5588 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005589 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005590 ->getNameStart());
5591
5592 case CXToken_Literal: {
5593 // We have stashed the starting pointer in the ptr_data field. Use it.
5594 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005595 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005596 }
5597
5598 case CXToken_Punctuation:
5599 case CXToken_Comment:
5600 break;
5601 }
5602
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005603 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005604 LOG_BAD_TU(TU);
5605 return cxstring::createEmpty();
5606 }
5607
Guy Benyei11169dd2012-12-18 14:30:41 +00005608 // We have to find the starting buffer pointer the hard way, by
5609 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005610 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005611 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005612 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005613
5614 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5615 std::pair<FileID, unsigned> LocInfo
5616 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5617 bool Invalid = false;
5618 StringRef Buffer
5619 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5620 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005621 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005622
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005623 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005624}
5625
5626CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005627 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005628 LOG_BAD_TU(TU);
5629 return clang_getNullLocation();
5630 }
5631
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005632 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005633 if (!CXXUnit)
5634 return clang_getNullLocation();
5635
5636 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5637 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5638}
5639
5640CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005641 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005642 LOG_BAD_TU(TU);
5643 return clang_getNullRange();
5644 }
5645
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005646 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005647 if (!CXXUnit)
5648 return clang_getNullRange();
5649
5650 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5651 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5652}
5653
5654static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5655 SmallVectorImpl<CXToken> &CXTokens) {
5656 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5657 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005658 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005659 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005660 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005661
5662 // Cannot tokenize across files.
5663 if (BeginLocInfo.first != EndLocInfo.first)
5664 return;
5665
5666 // Create a lexer
5667 bool Invalid = false;
5668 StringRef Buffer
5669 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5670 if (Invalid)
5671 return;
5672
5673 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5674 CXXUnit->getASTContext().getLangOpts(),
5675 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5676 Lex.SetCommentRetentionState(true);
5677
5678 // Lex tokens until we hit the end of the range.
5679 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5680 Token Tok;
5681 bool previousWasAt = false;
5682 do {
5683 // Lex the next token
5684 Lex.LexFromRawLexer(Tok);
5685 if (Tok.is(tok::eof))
5686 break;
5687
5688 // Initialize the CXToken.
5689 CXToken CXTok;
5690
5691 // - Common fields
5692 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5693 CXTok.int_data[2] = Tok.getLength();
5694 CXTok.int_data[3] = 0;
5695
5696 // - Kind-specific fields
5697 if (Tok.isLiteral()) {
5698 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005699 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005700 } else if (Tok.is(tok::raw_identifier)) {
5701 // Lookup the identifier to determine whether we have a keyword.
5702 IdentifierInfo *II
5703 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5704
5705 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5706 CXTok.int_data[0] = CXToken_Keyword;
5707 }
5708 else {
5709 CXTok.int_data[0] = Tok.is(tok::identifier)
5710 ? CXToken_Identifier
5711 : CXToken_Keyword;
5712 }
5713 CXTok.ptr_data = II;
5714 } else if (Tok.is(tok::comment)) {
5715 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005716 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005717 } else {
5718 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005719 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005720 }
5721 CXTokens.push_back(CXTok);
5722 previousWasAt = Tok.is(tok::at);
5723 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5724}
5725
5726void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5727 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005728 LOG_FUNC_SECTION {
5729 *Log << TU << ' ' << Range;
5730 }
5731
Guy Benyei11169dd2012-12-18 14:30:41 +00005732 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005733 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005734 if (NumTokens)
5735 *NumTokens = 0;
5736
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005737 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005738 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005739 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005740 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005741
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005742 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005743 if (!CXXUnit || !Tokens || !NumTokens)
5744 return;
5745
5746 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5747
5748 SourceRange R = cxloc::translateCXSourceRange(Range);
5749 if (R.isInvalid())
5750 return;
5751
5752 SmallVector<CXToken, 32> CXTokens;
5753 getTokens(CXXUnit, R, CXTokens);
5754
5755 if (CXTokens.empty())
5756 return;
5757
5758 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5759 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5760 *NumTokens = CXTokens.size();
5761}
5762
5763void clang_disposeTokens(CXTranslationUnit TU,
5764 CXToken *Tokens, unsigned NumTokens) {
5765 free(Tokens);
5766}
5767
5768} // end: extern "C"
5769
5770//===----------------------------------------------------------------------===//
5771// Token annotation APIs.
5772//===----------------------------------------------------------------------===//
5773
Guy Benyei11169dd2012-12-18 14:30:41 +00005774static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5775 CXCursor parent,
5776 CXClientData client_data);
5777static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5778 CXClientData client_data);
5779
5780namespace {
5781class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005782 CXToken *Tokens;
5783 CXCursor *Cursors;
5784 unsigned NumTokens;
5785 unsigned TokIdx;
5786 unsigned PreprocessingTokIdx;
5787 CursorVisitor AnnotateVis;
5788 SourceManager &SrcMgr;
5789 bool HasContextSensitiveKeywords;
5790
5791 struct PostChildrenInfo {
5792 CXCursor Cursor;
5793 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005794 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005795 unsigned BeforeChildrenTokenIdx;
5796 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005797 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005798
5799 CXToken &getTok(unsigned Idx) {
5800 assert(Idx < NumTokens);
5801 return Tokens[Idx];
5802 }
5803 const CXToken &getTok(unsigned Idx) const {
5804 assert(Idx < NumTokens);
5805 return Tokens[Idx];
5806 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005807 bool MoreTokens() const { return TokIdx < NumTokens; }
5808 unsigned NextToken() const { return TokIdx; }
5809 void AdvanceToken() { ++TokIdx; }
5810 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005811 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005812 }
5813 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005814 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005815 }
5816 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005817 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005818 }
5819
5820 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005821 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005822 SourceRange);
5823
5824public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005825 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005826 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005827 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005828 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005829 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005830 AnnotateTokensVisitor, this,
5831 /*VisitPreprocessorLast=*/true,
5832 /*VisitIncludedEntities=*/false,
5833 RegionOfInterest,
5834 /*VisitDeclsOnly=*/false,
5835 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005836 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005837 HasContextSensitiveKeywords(false) { }
5838
5839 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5840 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5841 bool postVisitChildren(CXCursor cursor);
5842 void AnnotateTokens();
5843
5844 /// \brief Determine whether the annotator saw any cursors that have
5845 /// context-sensitive keywords.
5846 bool hasContextSensitiveKeywords() const {
5847 return HasContextSensitiveKeywords;
5848 }
5849
5850 ~AnnotateTokensWorker() {
5851 assert(PostChildrenInfos.empty());
5852 }
5853};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00005854}
Guy Benyei11169dd2012-12-18 14:30:41 +00005855
5856void AnnotateTokensWorker::AnnotateTokens() {
5857 // Walk the AST within the region of interest, annotating tokens
5858 // along the way.
5859 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005860}
Guy Benyei11169dd2012-12-18 14:30:41 +00005861
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005862static inline void updateCursorAnnotation(CXCursor &Cursor,
5863 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005864 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005865 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005866 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005867}
5868
5869/// \brief It annotates and advances tokens with a cursor until the comparison
5870//// between the cursor location and the source range is the same as
5871/// \arg compResult.
5872///
5873/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5874/// Pass RangeOverlap to annotate tokens inside a range.
5875void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5876 RangeComparisonResult compResult,
5877 SourceRange range) {
5878 while (MoreTokens()) {
5879 const unsigned I = NextToken();
5880 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005881 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5882 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005883
5884 SourceLocation TokLoc = GetTokenLoc(I);
5885 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005886 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005887 AdvanceToken();
5888 continue;
5889 }
5890 break;
5891 }
5892}
5893
5894/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005895/// \returns true if it advanced beyond all macro tokens, false otherwise.
5896bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005897 CXCursor updateC,
5898 RangeComparisonResult compResult,
5899 SourceRange range) {
5900 assert(MoreTokens());
5901 assert(isFunctionMacroToken(NextToken()) &&
5902 "Should be called only for macro arg tokens");
5903
5904 // This works differently than annotateAndAdvanceTokens; because expanded
5905 // macro arguments can have arbitrary translation-unit source order, we do not
5906 // advance the token index one by one until a token fails the range test.
5907 // We only advance once past all of the macro arg tokens if all of them
5908 // pass the range test. If one of them fails we keep the token index pointing
5909 // at the start of the macro arg tokens so that the failing token will be
5910 // annotated by a subsequent annotation try.
5911
5912 bool atLeastOneCompFail = false;
5913
5914 unsigned I = NextToken();
5915 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5916 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5917 if (TokLoc.isFileID())
5918 continue; // not macro arg token, it's parens or comma.
5919 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5920 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5921 Cursors[I] = updateC;
5922 } else
5923 atLeastOneCompFail = true;
5924 }
5925
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005926 if (atLeastOneCompFail)
5927 return false;
5928
5929 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5930 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005931}
5932
5933enum CXChildVisitResult
5934AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005935 SourceRange cursorRange = getRawCursorExtent(cursor);
5936 if (cursorRange.isInvalid())
5937 return CXChildVisit_Recurse;
5938
5939 if (!HasContextSensitiveKeywords) {
5940 // Objective-C properties can have context-sensitive keywords.
5941 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005942 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005943 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5944 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5945 }
5946 // Objective-C methods can have context-sensitive keywords.
5947 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5948 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005949 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005950 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5951 if (Method->getObjCDeclQualifier())
5952 HasContextSensitiveKeywords = true;
5953 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005954 for (const auto *P : Method->params()) {
5955 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005956 HasContextSensitiveKeywords = true;
5957 break;
5958 }
5959 }
5960 }
5961 }
5962 }
5963 // C++ methods can have context-sensitive keywords.
5964 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005965 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005966 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5967 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5968 HasContextSensitiveKeywords = true;
5969 }
5970 }
5971 // C++ classes can have context-sensitive keywords.
5972 else if (cursor.kind == CXCursor_StructDecl ||
5973 cursor.kind == CXCursor_ClassDecl ||
5974 cursor.kind == CXCursor_ClassTemplate ||
5975 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005976 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005977 if (D->hasAttr<FinalAttr>())
5978 HasContextSensitiveKeywords = true;
5979 }
5980 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005981
5982 // Don't override a property annotation with its getter/setter method.
5983 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5984 parent.kind == CXCursor_ObjCPropertyDecl)
5985 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005986
5987 if (clang_isPreprocessing(cursor.kind)) {
5988 // Items in the preprocessing record are kept separate from items in
5989 // declarations, so we keep a separate token index.
5990 unsigned SavedTokIdx = TokIdx;
5991 TokIdx = PreprocessingTokIdx;
5992
5993 // Skip tokens up until we catch up to the beginning of the preprocessing
5994 // entry.
5995 while (MoreTokens()) {
5996 const unsigned I = NextToken();
5997 SourceLocation TokLoc = GetTokenLoc(I);
5998 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5999 case RangeBefore:
6000 AdvanceToken();
6001 continue;
6002 case RangeAfter:
6003 case RangeOverlap:
6004 break;
6005 }
6006 break;
6007 }
6008
6009 // Look at all of the tokens within this range.
6010 while (MoreTokens()) {
6011 const unsigned I = NextToken();
6012 SourceLocation TokLoc = GetTokenLoc(I);
6013 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
6014 case RangeBefore:
6015 llvm_unreachable("Infeasible");
6016 case RangeAfter:
6017 break;
6018 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006019 // For macro expansions, just note where the beginning of the macro
6020 // expansion occurs.
6021 if (cursor.kind == CXCursor_MacroExpansion) {
6022 if (TokLoc == cursorRange.getBegin())
6023 Cursors[I] = cursor;
6024 AdvanceToken();
6025 break;
6026 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006027 // We may have already annotated macro names inside macro definitions.
6028 if (Cursors[I].kind != CXCursor_MacroExpansion)
6029 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00006030 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00006031 continue;
6032 }
6033 break;
6034 }
6035
6036 // Save the preprocessing token index; restore the non-preprocessing
6037 // token index.
6038 PreprocessingTokIdx = TokIdx;
6039 TokIdx = SavedTokIdx;
6040 return CXChildVisit_Recurse;
6041 }
6042
6043 if (cursorRange.isInvalid())
6044 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006045
6046 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00006047 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006048 const enum CXCursorKind K = clang_getCursorKind(parent);
6049 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006050 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
6051 // Attributes are annotated out-of-order, skip tokens until we reach it.
6052 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00006053 ? clang_getNullCursor() : parent;
6054
6055 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
6056
6057 // Avoid having the cursor of an expression "overwrite" the annotation of the
6058 // variable declaration that it belongs to.
6059 // This can happen for C++ constructor expressions whose range generally
6060 // include the variable declaration, e.g.:
6061 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006062 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00006063 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00006064 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006065 const unsigned I = NextToken();
6066 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
6067 E->getLocStart() == D->getLocation() &&
6068 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006069 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00006070 AdvanceToken();
6071 }
6072 }
6073 }
6074
6075 // Before recursing into the children keep some state that we are going
6076 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
6077 // extra work after the child nodes are visited.
6078 // Note that we don't call VisitChildren here to avoid traversing statements
6079 // code-recursively which can blow the stack.
6080
6081 PostChildrenInfo Info;
6082 Info.Cursor = cursor;
6083 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006084 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006085 Info.BeforeChildrenTokenIdx = NextToken();
6086 PostChildrenInfos.push_back(Info);
6087
6088 return CXChildVisit_Recurse;
6089}
6090
6091bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
6092 if (PostChildrenInfos.empty())
6093 return false;
6094 const PostChildrenInfo &Info = PostChildrenInfos.back();
6095 if (!clang_equalCursors(Info.Cursor, cursor))
6096 return false;
6097
6098 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
6099 const unsigned AfterChildren = NextToken();
6100 SourceRange cursorRange = Info.CursorRange;
6101
6102 // Scan the tokens that are at the end of the cursor, but are not captured
6103 // but the child cursors.
6104 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
6105
6106 // Scan the tokens that are at the beginning of the cursor, but are not
6107 // capture by the child cursors.
6108 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
6109 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
6110 break;
6111
6112 Cursors[I] = cursor;
6113 }
6114
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006115 // Attributes are annotated out-of-order, rewind TokIdx to when we first
6116 // encountered the attribute cursor.
6117 if (clang_isAttribute(cursor.kind))
6118 TokIdx = Info.BeforeReachingCursorIdx;
6119
Guy Benyei11169dd2012-12-18 14:30:41 +00006120 PostChildrenInfos.pop_back();
6121 return false;
6122}
6123
6124static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
6125 CXCursor parent,
6126 CXClientData client_data) {
6127 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
6128}
6129
6130static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
6131 CXClientData client_data) {
6132 return static_cast<AnnotateTokensWorker*>(client_data)->
6133 postVisitChildren(cursor);
6134}
6135
6136namespace {
6137
6138/// \brief Uses the macro expansions in the preprocessing record to find
6139/// and mark tokens that are macro arguments. This info is used by the
6140/// AnnotateTokensWorker.
6141class MarkMacroArgTokensVisitor {
6142 SourceManager &SM;
6143 CXToken *Tokens;
6144 unsigned NumTokens;
6145 unsigned CurIdx;
6146
6147public:
6148 MarkMacroArgTokensVisitor(SourceManager &SM,
6149 CXToken *tokens, unsigned numTokens)
6150 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
6151
6152 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
6153 if (cursor.kind != CXCursor_MacroExpansion)
6154 return CXChildVisit_Continue;
6155
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006156 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00006157 if (macroRange.getBegin() == macroRange.getEnd())
6158 return CXChildVisit_Continue; // it's not a function macro.
6159
6160 for (; CurIdx < NumTokens; ++CurIdx) {
6161 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
6162 macroRange.getBegin()))
6163 break;
6164 }
6165
6166 if (CurIdx == NumTokens)
6167 return CXChildVisit_Break;
6168
6169 for (; CurIdx < NumTokens; ++CurIdx) {
6170 SourceLocation tokLoc = getTokenLoc(CurIdx);
6171 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
6172 break;
6173
6174 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
6175 }
6176
6177 if (CurIdx == NumTokens)
6178 return CXChildVisit_Break;
6179
6180 return CXChildVisit_Continue;
6181 }
6182
6183private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006184 CXToken &getTok(unsigned Idx) {
6185 assert(Idx < NumTokens);
6186 return Tokens[Idx];
6187 }
6188 const CXToken &getTok(unsigned Idx) const {
6189 assert(Idx < NumTokens);
6190 return Tokens[Idx];
6191 }
6192
Guy Benyei11169dd2012-12-18 14:30:41 +00006193 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006194 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006195 }
6196
6197 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
6198 // The third field is reserved and currently not used. Use it here
6199 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006200 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00006201 }
6202};
6203
6204} // end anonymous namespace
6205
6206static CXChildVisitResult
6207MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
6208 CXClientData client_data) {
6209 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
6210 parent);
6211}
6212
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006213/// \brief Used by \c annotatePreprocessorTokens.
6214/// \returns true if lexing was finished, false otherwise.
6215static bool lexNext(Lexer &Lex, Token &Tok,
6216 unsigned &NextIdx, unsigned NumTokens) {
6217 if (NextIdx >= NumTokens)
6218 return true;
6219
6220 ++NextIdx;
6221 Lex.LexFromRawLexer(Tok);
6222 if (Tok.is(tok::eof))
6223 return true;
6224
6225 return false;
6226}
6227
Guy Benyei11169dd2012-12-18 14:30:41 +00006228static void annotatePreprocessorTokens(CXTranslationUnit TU,
6229 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006230 CXCursor *Cursors,
6231 CXToken *Tokens,
6232 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006233 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006234
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006235 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00006236 SourceManager &SourceMgr = CXXUnit->getSourceManager();
6237 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006238 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00006239 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006240 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00006241
6242 if (BeginLocInfo.first != EndLocInfo.first)
6243 return;
6244
6245 StringRef Buffer;
6246 bool Invalid = false;
6247 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
6248 if (Buffer.empty() || Invalid)
6249 return;
6250
6251 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
6252 CXXUnit->getASTContext().getLangOpts(),
6253 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
6254 Buffer.end());
6255 Lex.SetCommentRetentionState(true);
6256
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006257 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006258 // Lex tokens in raw mode until we hit the end of the range, to avoid
6259 // entering #includes or expanding macros.
6260 while (true) {
6261 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006262 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6263 break;
6264 unsigned TokIdx = NextIdx-1;
6265 assert(Tok.getLocation() ==
6266 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006267
6268 reprocess:
6269 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006270 // We have found a preprocessing directive. Annotate the tokens
6271 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00006272 //
6273 // FIXME: Some simple tests here could identify macro definitions and
6274 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006275
6276 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006277 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6278 break;
6279
Craig Topper69186e72014-06-08 08:38:04 +00006280 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00006281 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006282 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6283 break;
6284
6285 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00006286 IdentifierInfo &II =
6287 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006288 SourceLocation MappedTokLoc =
6289 CXXUnit->mapLocationToPreamble(Tok.getLocation());
6290 MI = getMacroInfo(II, MappedTokLoc, TU);
6291 }
6292 }
6293
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006294 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00006295 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006296 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
6297 finished = true;
6298 break;
6299 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006300 // If we are in a macro definition, check if the token was ever a
6301 // macro name and annotate it if that's the case.
6302 if (MI) {
6303 SourceLocation SaveLoc = Tok.getLocation();
6304 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
Richard Smith66a81862015-05-04 02:25:31 +00006305 MacroDefinitionRecord *MacroDef =
6306 checkForMacroInMacroDefinition(MI, Tok, TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006307 Tok.setLocation(SaveLoc);
6308 if (MacroDef)
Richard Smith66a81862015-05-04 02:25:31 +00006309 Cursors[NextIdx - 1] =
6310 MakeMacroExpansionCursor(MacroDef, Tok.getLocation(), TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006311 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006312 } while (!Tok.isAtStartOfLine());
6313
6314 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
6315 assert(TokIdx <= LastIdx);
6316 SourceLocation EndLoc =
6317 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
6318 CXCursor Cursor =
6319 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
6320
6321 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006322 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006323
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006324 if (finished)
6325 break;
6326 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00006327 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006328 }
6329}
6330
6331// This gets run a separate thread to avoid stack blowout.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006332static void clang_annotateTokensImpl(CXTranslationUnit TU, ASTUnit *CXXUnit,
6333 CXToken *Tokens, unsigned NumTokens,
6334 CXCursor *Cursors) {
Dmitri Gribenko183436e2013-01-26 21:49:50 +00006335 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006336 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
6337 setThreadBackgroundPriority();
6338
6339 // Determine the region of interest, which contains all of the tokens.
6340 SourceRange RegionOfInterest;
6341 RegionOfInterest.setBegin(
6342 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
6343 RegionOfInterest.setEnd(
6344 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
6345 Tokens[NumTokens-1])));
6346
Guy Benyei11169dd2012-12-18 14:30:41 +00006347 // Relex the tokens within the source range to look for preprocessing
6348 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006349 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006350
6351 // If begin location points inside a macro argument, set it to the expansion
6352 // location so we can have the full context when annotating semantically.
6353 {
6354 SourceManager &SM = CXXUnit->getSourceManager();
6355 SourceLocation Loc =
6356 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
6357 if (Loc.isMacroID())
6358 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
6359 }
6360
Guy Benyei11169dd2012-12-18 14:30:41 +00006361 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
6362 // Search and mark tokens that are macro argument expansions.
6363 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
6364 Tokens, NumTokens);
6365 CursorVisitor MacroArgMarker(TU,
6366 MarkMacroArgTokensVisitorDelegate, &Visitor,
6367 /*VisitPreprocessorLast=*/true,
6368 /*VisitIncludedEntities=*/false,
6369 RegionOfInterest);
6370 MacroArgMarker.visitPreprocessedEntitiesInRegion();
6371 }
6372
6373 // Annotate all of the source locations in the region of interest that map to
6374 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006375 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00006376
6377 // FIXME: We use a ridiculous stack size here because the data-recursion
6378 // algorithm uses a large stack frame than the non-data recursive version,
6379 // and AnnotationTokensWorker currently transforms the data-recursion
6380 // algorithm back into a traditional recursion by explicitly calling
6381 // VisitChildren(). We will need to remove this explicit recursive call.
6382 W.AnnotateTokens();
6383
6384 // If we ran into any entities that involve context-sensitive keywords,
6385 // take another pass through the tokens to mark them as such.
6386 if (W.hasContextSensitiveKeywords()) {
6387 for (unsigned I = 0; I != NumTokens; ++I) {
6388 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
6389 continue;
6390
6391 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
6392 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006393 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006394 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
6395 if (Property->getPropertyAttributesAsWritten() != 0 &&
6396 llvm::StringSwitch<bool>(II->getName())
6397 .Case("readonly", true)
6398 .Case("assign", true)
6399 .Case("unsafe_unretained", true)
6400 .Case("readwrite", true)
6401 .Case("retain", true)
6402 .Case("copy", true)
6403 .Case("nonatomic", true)
6404 .Case("atomic", true)
6405 .Case("getter", true)
6406 .Case("setter", true)
6407 .Case("strong", true)
6408 .Case("weak", true)
6409 .Default(false))
6410 Tokens[I].int_data[0] = CXToken_Keyword;
6411 }
6412 continue;
6413 }
6414
6415 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6416 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6417 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6418 if (llvm::StringSwitch<bool>(II->getName())
6419 .Case("in", true)
6420 .Case("out", true)
6421 .Case("inout", true)
6422 .Case("oneway", true)
6423 .Case("bycopy", true)
6424 .Case("byref", true)
6425 .Default(false))
6426 Tokens[I].int_data[0] = CXToken_Keyword;
6427 continue;
6428 }
6429
6430 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6431 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6432 Tokens[I].int_data[0] = CXToken_Keyword;
6433 continue;
6434 }
6435 }
6436 }
6437}
6438
6439extern "C" {
6440
6441void clang_annotateTokens(CXTranslationUnit TU,
6442 CXToken *Tokens, unsigned NumTokens,
6443 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006444 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006445 LOG_BAD_TU(TU);
6446 return;
6447 }
6448 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006449 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006450 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006451 }
6452
6453 LOG_FUNC_SECTION {
6454 *Log << TU << ' ';
6455 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6456 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6457 *Log << clang_getRange(bloc, eloc);
6458 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006459
6460 // Any token we don't specifically annotate will have a NULL cursor.
6461 CXCursor C = clang_getNullCursor();
6462 for (unsigned I = 0; I != NumTokens; ++I)
6463 Cursors[I] = C;
6464
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006465 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006466 if (!CXXUnit)
6467 return;
6468
6469 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006470
6471 auto AnnotateTokensImpl = [=]() {
6472 clang_annotateTokensImpl(TU, CXXUnit, Tokens, NumTokens, Cursors);
6473 };
Guy Benyei11169dd2012-12-18 14:30:41 +00006474 llvm::CrashRecoveryContext CRC;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006475 if (!RunSafely(CRC, AnnotateTokensImpl, GetSafetyThreadStackSize() * 2)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006476 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6477 }
6478}
6479
6480} // end: extern "C"
6481
6482//===----------------------------------------------------------------------===//
6483// Operations for querying linkage of a cursor.
6484//===----------------------------------------------------------------------===//
6485
6486extern "C" {
6487CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6488 if (!clang_isDeclaration(cursor.kind))
6489 return CXLinkage_Invalid;
6490
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006491 const Decl *D = cxcursor::getCursorDecl(cursor);
6492 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006493 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006494 case NoLinkage:
6495 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006496 case InternalLinkage: return CXLinkage_Internal;
6497 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6498 case ExternalLinkage: return CXLinkage_External;
6499 };
6500
6501 return CXLinkage_Invalid;
6502}
6503} // end: extern "C"
6504
6505//===----------------------------------------------------------------------===//
Ehsan Akhgari93697fa2015-11-23 19:56:46 +00006506// Operations for querying visibility of a cursor.
6507//===----------------------------------------------------------------------===//
6508
6509extern "C" {
6510CXVisibilityKind clang_getCursorVisibility(CXCursor cursor) {
6511 if (!clang_isDeclaration(cursor.kind))
6512 return CXVisibility_Invalid;
6513
6514 const Decl *D = cxcursor::getCursorDecl(cursor);
6515 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
6516 switch (ND->getVisibility()) {
6517 case HiddenVisibility: return CXVisibility_Hidden;
6518 case ProtectedVisibility: return CXVisibility_Protected;
6519 case DefaultVisibility: return CXVisibility_Default;
6520 };
6521
6522 return CXVisibility_Invalid;
6523}
6524} // end: extern "C"
6525
6526//===----------------------------------------------------------------------===//
Guy Benyei11169dd2012-12-18 14:30:41 +00006527// Operations for querying language of a cursor.
6528//===----------------------------------------------------------------------===//
6529
6530static CXLanguageKind getDeclLanguage(const Decl *D) {
6531 if (!D)
6532 return CXLanguage_C;
6533
6534 switch (D->getKind()) {
6535 default:
6536 break;
6537 case Decl::ImplicitParam:
6538 case Decl::ObjCAtDefsField:
6539 case Decl::ObjCCategory:
6540 case Decl::ObjCCategoryImpl:
6541 case Decl::ObjCCompatibleAlias:
6542 case Decl::ObjCImplementation:
6543 case Decl::ObjCInterface:
6544 case Decl::ObjCIvar:
6545 case Decl::ObjCMethod:
6546 case Decl::ObjCProperty:
6547 case Decl::ObjCPropertyImpl:
6548 case Decl::ObjCProtocol:
Douglas Gregor85f3f952015-07-07 03:57:15 +00006549 case Decl::ObjCTypeParam:
Guy Benyei11169dd2012-12-18 14:30:41 +00006550 return CXLanguage_ObjC;
6551 case Decl::CXXConstructor:
6552 case Decl::CXXConversion:
6553 case Decl::CXXDestructor:
6554 case Decl::CXXMethod:
6555 case Decl::CXXRecord:
6556 case Decl::ClassTemplate:
6557 case Decl::ClassTemplatePartialSpecialization:
6558 case Decl::ClassTemplateSpecialization:
6559 case Decl::Friend:
6560 case Decl::FriendTemplate:
6561 case Decl::FunctionTemplate:
6562 case Decl::LinkageSpec:
6563 case Decl::Namespace:
6564 case Decl::NamespaceAlias:
6565 case Decl::NonTypeTemplateParm:
6566 case Decl::StaticAssert:
6567 case Decl::TemplateTemplateParm:
6568 case Decl::TemplateTypeParm:
6569 case Decl::UnresolvedUsingTypename:
6570 case Decl::UnresolvedUsingValue:
6571 case Decl::Using:
6572 case Decl::UsingDirective:
6573 case Decl::UsingShadow:
6574 return CXLanguage_CPlusPlus;
6575 }
6576
6577 return CXLanguage_C;
6578}
6579
6580extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006581
6582static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6583 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
Manuel Klimek8e3a7ed2015-09-25 17:53:16 +00006584 return CXAvailability_NotAvailable;
Guy Benyei11169dd2012-12-18 14:30:41 +00006585
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006586 switch (D->getAvailability()) {
6587 case AR_Available:
6588 case AR_NotYetIntroduced:
6589 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006590 return getCursorAvailabilityForDecl(
6591 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006592 return CXAvailability_Available;
6593
6594 case AR_Deprecated:
6595 return CXAvailability_Deprecated;
6596
6597 case AR_Unavailable:
6598 return CXAvailability_NotAvailable;
6599 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006600
6601 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006602}
6603
Guy Benyei11169dd2012-12-18 14:30:41 +00006604enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6605 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006606 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6607 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006608
6609 return CXAvailability_Available;
6610}
6611
6612static CXVersion convertVersion(VersionTuple In) {
6613 CXVersion Out = { -1, -1, -1 };
6614 if (In.empty())
6615 return Out;
6616
6617 Out.Major = In.getMajor();
6618
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006619 Optional<unsigned> Minor = In.getMinor();
6620 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006621 Out.Minor = *Minor;
6622 else
6623 return Out;
6624
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006625 Optional<unsigned> Subminor = In.getSubminor();
6626 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006627 Out.Subminor = *Subminor;
6628
6629 return Out;
6630}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006631
6632static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6633 int *always_deprecated,
6634 CXString *deprecated_message,
6635 int *always_unavailable,
6636 CXString *unavailable_message,
6637 CXPlatformAvailability *availability,
6638 int availability_size) {
6639 bool HadAvailAttr = false;
6640 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006641 for (auto A : D->attrs()) {
6642 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006643 HadAvailAttr = true;
6644 if (always_deprecated)
6645 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006646 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006647 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006648 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006649 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006650 continue;
6651 }
6652
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006653 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006654 HadAvailAttr = true;
6655 if (always_unavailable)
6656 *always_unavailable = 1;
6657 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006658 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006659 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6660 }
6661 continue;
6662 }
6663
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006664 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006665 HadAvailAttr = true;
6666 if (N < availability_size) {
6667 availability[N].Platform
6668 = cxstring::createDup(Avail->getPlatform()->getName());
6669 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6670 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6671 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6672 availability[N].Unavailable = Avail->getUnavailable();
6673 availability[N].Message = cxstring::createDup(Avail->getMessage());
6674 }
6675 ++N;
6676 }
6677 }
6678
6679 if (!HadAvailAttr)
6680 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6681 return getCursorPlatformAvailabilityForDecl(
6682 cast<Decl>(EnumConst->getDeclContext()),
6683 always_deprecated,
6684 deprecated_message,
6685 always_unavailable,
6686 unavailable_message,
6687 availability,
6688 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006689
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006690 return N;
6691}
6692
Guy Benyei11169dd2012-12-18 14:30:41 +00006693int clang_getCursorPlatformAvailability(CXCursor cursor,
6694 int *always_deprecated,
6695 CXString *deprecated_message,
6696 int *always_unavailable,
6697 CXString *unavailable_message,
6698 CXPlatformAvailability *availability,
6699 int availability_size) {
6700 if (always_deprecated)
6701 *always_deprecated = 0;
6702 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006703 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006704 if (always_unavailable)
6705 *always_unavailable = 0;
6706 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006707 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006708
Guy Benyei11169dd2012-12-18 14:30:41 +00006709 if (!clang_isDeclaration(cursor.kind))
6710 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006711
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006712 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006713 if (!D)
6714 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006715
6716 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6717 deprecated_message,
6718 always_unavailable,
6719 unavailable_message,
6720 availability,
6721 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006722}
6723
6724void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6725 clang_disposeString(availability->Platform);
6726 clang_disposeString(availability->Message);
6727}
6728
6729CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6730 if (clang_isDeclaration(cursor.kind))
6731 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6732
6733 return CXLanguage_Invalid;
6734}
6735
6736 /// \brief If the given cursor is the "templated" declaration
6737 /// descibing a class or function template, return the class or
6738 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006739static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006740 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006741 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006742
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006743 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006744 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6745 return FunTmpl;
6746
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006747 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006748 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6749 return ClassTmpl;
6750
6751 return D;
6752}
6753
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006754
6755enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
6756 StorageClass sc = SC_None;
6757 const Decl *D = getCursorDecl(C);
6758 if (D) {
6759 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
6760 sc = FD->getStorageClass();
6761 } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
6762 sc = VD->getStorageClass();
6763 } else {
6764 return CX_SC_Invalid;
6765 }
6766 } else {
6767 return CX_SC_Invalid;
6768 }
6769 switch (sc) {
6770 case SC_None:
6771 return CX_SC_None;
6772 case SC_Extern:
6773 return CX_SC_Extern;
6774 case SC_Static:
6775 return CX_SC_Static;
6776 case SC_PrivateExtern:
6777 return CX_SC_PrivateExtern;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006778 case SC_Auto:
6779 return CX_SC_Auto;
6780 case SC_Register:
6781 return CX_SC_Register;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006782 }
Kaelyn Takataab61e702014-10-15 18:03:26 +00006783 llvm_unreachable("Unhandled storage class!");
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006784}
6785
Guy Benyei11169dd2012-12-18 14:30:41 +00006786CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6787 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006788 if (const Decl *D = getCursorDecl(cursor)) {
6789 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006790 if (!DC)
6791 return clang_getNullCursor();
6792
6793 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6794 getCursorTU(cursor));
6795 }
6796 }
6797
6798 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006799 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006800 return MakeCXCursor(D, getCursorTU(cursor));
6801 }
6802
6803 return clang_getNullCursor();
6804}
6805
6806CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6807 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006808 if (const Decl *D = getCursorDecl(cursor)) {
6809 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006810 if (!DC)
6811 return clang_getNullCursor();
6812
6813 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6814 getCursorTU(cursor));
6815 }
6816 }
6817
6818 // FIXME: Note that we can't easily compute the lexical context of a
6819 // statement or expression, so we return nothing.
6820 return clang_getNullCursor();
6821}
6822
6823CXFile clang_getIncludedFile(CXCursor cursor) {
6824 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006825 return nullptr;
6826
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006827 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006828 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006829}
6830
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006831unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6832 if (C.kind != CXCursor_ObjCPropertyDecl)
6833 return CXObjCPropertyAttr_noattr;
6834
6835 unsigned Result = CXObjCPropertyAttr_noattr;
6836 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6837 ObjCPropertyDecl::PropertyAttributeKind Attr =
6838 PD->getPropertyAttributesAsWritten();
6839
6840#define SET_CXOBJCPROP_ATTR(A) \
6841 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6842 Result |= CXObjCPropertyAttr_##A
6843 SET_CXOBJCPROP_ATTR(readonly);
6844 SET_CXOBJCPROP_ATTR(getter);
6845 SET_CXOBJCPROP_ATTR(assign);
6846 SET_CXOBJCPROP_ATTR(readwrite);
6847 SET_CXOBJCPROP_ATTR(retain);
6848 SET_CXOBJCPROP_ATTR(copy);
6849 SET_CXOBJCPROP_ATTR(nonatomic);
6850 SET_CXOBJCPROP_ATTR(setter);
6851 SET_CXOBJCPROP_ATTR(atomic);
6852 SET_CXOBJCPROP_ATTR(weak);
6853 SET_CXOBJCPROP_ATTR(strong);
6854 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6855#undef SET_CXOBJCPROP_ATTR
6856
6857 return Result;
6858}
6859
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006860unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6861 if (!clang_isDeclaration(C.kind))
6862 return CXObjCDeclQualifier_None;
6863
6864 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6865 const Decl *D = getCursorDecl(C);
6866 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6867 QT = MD->getObjCDeclQualifier();
6868 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6869 QT = PD->getObjCDeclQualifier();
6870 if (QT == Decl::OBJC_TQ_None)
6871 return CXObjCDeclQualifier_None;
6872
6873 unsigned Result = CXObjCDeclQualifier_None;
6874 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6875 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6876 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6877 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6878 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6879 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6880
6881 return Result;
6882}
6883
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006884unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6885 if (!clang_isDeclaration(C.kind))
6886 return 0;
6887
6888 const Decl *D = getCursorDecl(C);
6889 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6890 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6891 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6892 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6893
6894 return 0;
6895}
6896
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006897unsigned clang_Cursor_isVariadic(CXCursor C) {
6898 if (!clang_isDeclaration(C.kind))
6899 return 0;
6900
6901 const Decl *D = getCursorDecl(C);
6902 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6903 return FD->isVariadic();
6904 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6905 return MD->isVariadic();
6906
6907 return 0;
6908}
6909
Guy Benyei11169dd2012-12-18 14:30:41 +00006910CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6911 if (!clang_isDeclaration(C.kind))
6912 return clang_getNullRange();
6913
6914 const Decl *D = getCursorDecl(C);
6915 ASTContext &Context = getCursorContext(C);
6916 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6917 if (!RC)
6918 return clang_getNullRange();
6919
6920 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6921}
6922
6923CXString clang_Cursor_getRawCommentText(CXCursor C) {
6924 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006925 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006926
6927 const Decl *D = getCursorDecl(C);
6928 ASTContext &Context = getCursorContext(C);
6929 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6930 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6931 StringRef();
6932
6933 // Don't duplicate the string because RawText points directly into source
6934 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006935 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006936}
6937
6938CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6939 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006940 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006941
6942 const Decl *D = getCursorDecl(C);
6943 const ASTContext &Context = getCursorContext(C);
6944 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6945
6946 if (RC) {
6947 StringRef BriefText = RC->getBriefText(Context);
6948
6949 // Don't duplicate the string because RawComment ensures that this memory
6950 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006951 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006952 }
6953
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006954 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006955}
6956
Guy Benyei11169dd2012-12-18 14:30:41 +00006957CXModule clang_Cursor_getModule(CXCursor C) {
6958 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006959 if (const ImportDecl *ImportD =
6960 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006961 return ImportD->getImportedModule();
6962 }
6963
Craig Topper69186e72014-06-08 08:38:04 +00006964 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006965}
6966
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006967CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6968 if (isNotUsableTU(TU)) {
6969 LOG_BAD_TU(TU);
6970 return nullptr;
6971 }
6972 if (!File)
6973 return nullptr;
6974 FileEntry *FE = static_cast<FileEntry *>(File);
6975
6976 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6977 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6978 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6979
Richard Smithfeb54b62014-10-23 02:01:19 +00006980 return Header.getModule();
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006981}
6982
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006983CXFile clang_Module_getASTFile(CXModule CXMod) {
6984 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006985 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006986 Module *Mod = static_cast<Module*>(CXMod);
6987 return const_cast<FileEntry *>(Mod->getASTFile());
6988}
6989
Guy Benyei11169dd2012-12-18 14:30:41 +00006990CXModule clang_Module_getParent(CXModule CXMod) {
6991 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006992 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006993 Module *Mod = static_cast<Module*>(CXMod);
6994 return Mod->Parent;
6995}
6996
6997CXString clang_Module_getName(CXModule CXMod) {
6998 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006999 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00007000 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007001 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00007002}
7003
7004CXString clang_Module_getFullName(CXModule CXMod) {
7005 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007006 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00007007 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007008 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00007009}
7010
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00007011int clang_Module_isSystem(CXModule CXMod) {
7012 if (!CXMod)
7013 return 0;
7014 Module *Mod = static_cast<Module*>(CXMod);
7015 return Mod->IsSystem;
7016}
7017
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007018unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
7019 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007020 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007021 LOG_BAD_TU(TU);
7022 return 0;
7023 }
7024 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00007025 return 0;
7026 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007027 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
7028 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
7029 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00007030}
7031
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007032CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
7033 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007034 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007035 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00007036 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007037 }
7038 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00007039 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007040 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007041 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00007042
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007043 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
7044 if (Index < TopHeaders.size())
7045 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00007046
Craig Topper69186e72014-06-08 08:38:04 +00007047 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007048}
7049
7050} // end: extern "C"
7051
7052//===----------------------------------------------------------------------===//
7053// C++ AST instrospection.
7054//===----------------------------------------------------------------------===//
7055
7056extern "C" {
Saleem Abdulrasool6ea75db2015-10-27 15:50:22 +00007057unsigned clang_CXXField_isMutable(CXCursor C) {
7058 if (!clang_isDeclaration(C.kind))
7059 return 0;
7060
7061 if (const auto D = cxcursor::getCursorDecl(C))
7062 if (const auto FD = dyn_cast_or_null<FieldDecl>(D))
7063 return FD->isMutable() ? 1 : 0;
7064 return 0;
7065}
7066
Dmitri Gribenko62770be2013-05-17 18:38:35 +00007067unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
7068 if (!clang_isDeclaration(C.kind))
7069 return 0;
7070
Dmitri Gribenko62770be2013-05-17 18:38:35 +00007071 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007072 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007073 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00007074 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
7075}
7076
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00007077unsigned clang_CXXMethod_isConst(CXCursor C) {
7078 if (!clang_isDeclaration(C.kind))
7079 return 0;
7080
7081 const Decl *D = cxcursor::getCursorDecl(C);
7082 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007083 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00007084 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
7085}
7086
Guy Benyei11169dd2012-12-18 14:30:41 +00007087unsigned clang_CXXMethod_isStatic(CXCursor C) {
7088 if (!clang_isDeclaration(C.kind))
7089 return 0;
7090
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007091 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007092 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007093 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007094 return (Method && Method->isStatic()) ? 1 : 0;
7095}
7096
7097unsigned clang_CXXMethod_isVirtual(CXCursor C) {
7098 if (!clang_isDeclaration(C.kind))
7099 return 0;
7100
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007101 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007102 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007103 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007104 return (Method && Method->isVirtual()) ? 1 : 0;
7105}
7106} // end: extern "C"
7107
7108//===----------------------------------------------------------------------===//
7109// Attribute introspection.
7110//===----------------------------------------------------------------------===//
7111
7112extern "C" {
7113CXType clang_getIBOutletCollectionType(CXCursor C) {
7114 if (C.kind != CXCursor_IBOutletCollectionAttr)
7115 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
7116
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00007117 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00007118 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
7119
7120 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
7121}
7122} // end: extern "C"
7123
7124//===----------------------------------------------------------------------===//
7125// Inspecting memory usage.
7126//===----------------------------------------------------------------------===//
7127
7128typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
7129
7130static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
7131 enum CXTUResourceUsageKind k,
7132 unsigned long amount) {
7133 CXTUResourceUsageEntry entry = { k, amount };
7134 entries.push_back(entry);
7135}
7136
7137extern "C" {
7138
7139const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
7140 const char *str = "";
7141 switch (kind) {
7142 case CXTUResourceUsage_AST:
7143 str = "ASTContext: expressions, declarations, and types";
7144 break;
7145 case CXTUResourceUsage_Identifiers:
7146 str = "ASTContext: identifiers";
7147 break;
7148 case CXTUResourceUsage_Selectors:
7149 str = "ASTContext: selectors";
7150 break;
7151 case CXTUResourceUsage_GlobalCompletionResults:
7152 str = "Code completion: cached global results";
7153 break;
7154 case CXTUResourceUsage_SourceManagerContentCache:
7155 str = "SourceManager: content cache allocator";
7156 break;
7157 case CXTUResourceUsage_AST_SideTables:
7158 str = "ASTContext: side tables";
7159 break;
7160 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
7161 str = "SourceManager: malloc'ed memory buffers";
7162 break;
7163 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
7164 str = "SourceManager: mmap'ed memory buffers";
7165 break;
7166 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
7167 str = "ExternalASTSource: malloc'ed memory buffers";
7168 break;
7169 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
7170 str = "ExternalASTSource: mmap'ed memory buffers";
7171 break;
7172 case CXTUResourceUsage_Preprocessor:
7173 str = "Preprocessor: malloc'ed memory";
7174 break;
7175 case CXTUResourceUsage_PreprocessingRecord:
7176 str = "Preprocessor: PreprocessingRecord";
7177 break;
7178 case CXTUResourceUsage_SourceManager_DataStructures:
7179 str = "SourceManager: data structures and tables";
7180 break;
7181 case CXTUResourceUsage_Preprocessor_HeaderSearch:
7182 str = "Preprocessor: header search tables";
7183 break;
7184 }
7185 return str;
7186}
7187
7188CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007189 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007190 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00007191 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00007192 return usage;
7193 }
7194
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007195 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00007196 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00007197 ASTContext &astContext = astUnit->getASTContext();
7198
7199 // How much memory is used by AST nodes and types?
7200 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
7201 (unsigned long) astContext.getASTAllocatedMemory());
7202
7203 // How much memory is used by identifiers?
7204 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
7205 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
7206
7207 // How much memory is used for selectors?
7208 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
7209 (unsigned long) astContext.Selectors.getTotalMemory());
7210
7211 // How much memory is used by ASTContext's side tables?
7212 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
7213 (unsigned long) astContext.getSideTableAllocatedMemory());
7214
7215 // How much memory is used for caching global code completion results?
7216 unsigned long completionBytes = 0;
7217 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00007218 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007219 completionBytes = completionAllocator->getTotalMemory();
7220 }
7221 createCXTUResourceUsageEntry(*entries,
7222 CXTUResourceUsage_GlobalCompletionResults,
7223 completionBytes);
7224
7225 // How much memory is being used by SourceManager's content cache?
7226 createCXTUResourceUsageEntry(*entries,
7227 CXTUResourceUsage_SourceManagerContentCache,
7228 (unsigned long) astContext.getSourceManager().getContentCacheSize());
7229
7230 // How much memory is being used by the MemoryBuffer's in SourceManager?
7231 const SourceManager::MemoryBufferSizes &srcBufs =
7232 astUnit->getSourceManager().getMemoryBufferSizes();
7233
7234 createCXTUResourceUsageEntry(*entries,
7235 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
7236 (unsigned long) srcBufs.malloc_bytes);
7237 createCXTUResourceUsageEntry(*entries,
7238 CXTUResourceUsage_SourceManager_Membuffer_MMap,
7239 (unsigned long) srcBufs.mmap_bytes);
7240 createCXTUResourceUsageEntry(*entries,
7241 CXTUResourceUsage_SourceManager_DataStructures,
7242 (unsigned long) astContext.getSourceManager()
7243 .getDataStructureSizes());
7244
7245 // How much memory is being used by the ExternalASTSource?
7246 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
7247 const ExternalASTSource::MemoryBufferSizes &sizes =
7248 esrc->getMemoryBufferSizes();
7249
7250 createCXTUResourceUsageEntry(*entries,
7251 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
7252 (unsigned long) sizes.malloc_bytes);
7253 createCXTUResourceUsageEntry(*entries,
7254 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
7255 (unsigned long) sizes.mmap_bytes);
7256 }
7257
7258 // How much memory is being used by the Preprocessor?
7259 Preprocessor &pp = astUnit->getPreprocessor();
7260 createCXTUResourceUsageEntry(*entries,
7261 CXTUResourceUsage_Preprocessor,
7262 pp.getTotalMemory());
7263
7264 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
7265 createCXTUResourceUsageEntry(*entries,
7266 CXTUResourceUsage_PreprocessingRecord,
7267 pRec->getTotalMemory());
7268 }
7269
7270 createCXTUResourceUsageEntry(*entries,
7271 CXTUResourceUsage_Preprocessor_HeaderSearch,
7272 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00007273
Guy Benyei11169dd2012-12-18 14:30:41 +00007274 CXTUResourceUsage usage = { (void*) entries.get(),
7275 (unsigned) entries->size(),
Alexander Kornienko6ee521c2015-01-23 15:36:10 +00007276 !entries->empty() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00007277 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00007278 return usage;
7279}
7280
7281void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
7282 if (usage.data)
7283 delete (MemUsageEntries*) usage.data;
7284}
7285
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007286CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
7287 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007288 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00007289 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007290
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007291 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007292 LOG_BAD_TU(TU);
7293 return skipped;
7294 }
7295
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007296 if (!file)
7297 return skipped;
7298
7299 ASTUnit *astUnit = cxtu::getASTUnit(TU);
7300 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
7301 if (!ppRec)
7302 return skipped;
7303
7304 ASTContext &Ctx = astUnit->getASTContext();
7305 SourceManager &sm = Ctx.getSourceManager();
7306 FileEntry *fileEntry = static_cast<FileEntry *>(file);
7307 FileID wantedFileID = sm.translateFile(fileEntry);
7308
7309 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
7310 std::vector<SourceRange> wantedRanges;
7311 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
7312 i != ei; ++i) {
7313 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
7314 wantedRanges.push_back(*i);
7315 }
7316
7317 skipped->count = wantedRanges.size();
7318 skipped->ranges = new CXSourceRange[skipped->count];
7319 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
7320 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
7321
7322 return skipped;
7323}
7324
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007325void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
7326 if (ranges) {
7327 delete[] ranges->ranges;
7328 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007329 }
7330}
7331
Guy Benyei11169dd2012-12-18 14:30:41 +00007332} // end extern "C"
7333
7334void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
7335 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
7336 for (unsigned I = 0; I != Usage.numEntries; ++I)
7337 fprintf(stderr, " %s: %lu\n",
7338 clang_getTUResourceUsageName(Usage.entries[I].kind),
7339 Usage.entries[I].amount);
7340
7341 clang_disposeCXTUResourceUsage(Usage);
7342}
7343
7344//===----------------------------------------------------------------------===//
7345// Misc. utility functions.
7346//===----------------------------------------------------------------------===//
7347
7348/// Default to using an 8 MB stack size on "safety" threads.
7349static unsigned SafetyStackThreadSize = 8 << 20;
7350
7351namespace clang {
7352
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007353bool RunSafely(llvm::CrashRecoveryContext &CRC, llvm::function_ref<void()> Fn,
Guy Benyei11169dd2012-12-18 14:30:41 +00007354 unsigned Size) {
7355 if (!Size)
7356 Size = GetSafetyThreadStackSize();
7357 if (Size)
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007358 return CRC.RunSafelyOnThread(Fn, Size);
7359 return CRC.RunSafely(Fn);
Guy Benyei11169dd2012-12-18 14:30:41 +00007360}
7361
7362unsigned GetSafetyThreadStackSize() {
7363 return SafetyStackThreadSize;
7364}
7365
7366void SetSafetyThreadStackSize(unsigned Value) {
7367 SafetyStackThreadSize = Value;
7368}
7369
Alexander Kornienkoab9db512015-06-22 23:07:51 +00007370}
Guy Benyei11169dd2012-12-18 14:30:41 +00007371
7372void clang::setThreadBackgroundPriority() {
7373 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
7374 return;
7375
Alp Toker1a86ad22014-07-06 06:24:00 +00007376#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00007377 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
7378#endif
7379}
7380
7381void cxindex::printDiagsToStderr(ASTUnit *Unit) {
7382 if (!Unit)
7383 return;
7384
7385 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
7386 DEnd = Unit->stored_diag_end();
7387 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00007388 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00007389 CXString Msg = clang_formatDiagnostic(&Diag,
7390 clang_defaultDiagnosticDisplayOptions());
7391 fprintf(stderr, "%s\n", clang_getCString(Msg));
7392 clang_disposeString(Msg);
7393 }
7394#ifdef LLVM_ON_WIN32
7395 // On Windows, force a flush, since there may be multiple copies of
7396 // stderr and stdout in the file system, all with different buffers
7397 // but writing to the same device.
7398 fflush(stderr);
7399#endif
7400}
7401
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007402MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
7403 SourceLocation MacroDefLoc,
7404 CXTranslationUnit TU){
7405 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007406 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007407 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007408 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007409
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007410 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007411 Preprocessor &PP = Unit->getPreprocessor();
Richard Smith20e883e2015-04-29 23:20:19 +00007412 MacroDirective *MD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007413 if (MD) {
7414 for (MacroDirective::DefInfo
7415 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
7416 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
7417 return Def.getMacroInfo();
7418 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007419 }
7420
Craig Topper69186e72014-06-08 08:38:04 +00007421 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007422}
7423
Richard Smith66a81862015-05-04 02:25:31 +00007424const MacroInfo *cxindex::getMacroInfo(const MacroDefinitionRecord *MacroDef,
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007425 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007426 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007427 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007428 const IdentifierInfo *II = MacroDef->getName();
7429 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00007430 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007431
7432 return getMacroInfo(*II, MacroDef->getLocation(), TU);
7433}
7434
Richard Smith66a81862015-05-04 02:25:31 +00007435MacroDefinitionRecord *
7436cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, const Token &Tok,
7437 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007438 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007439 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007440 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00007441 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007442
7443 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007444 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007445 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
7446 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007447 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007448
7449 // Check that the token is inside the definition and not its argument list.
7450 SourceManager &SM = Unit->getSourceManager();
7451 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00007452 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007453 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00007454 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007455
7456 Preprocessor &PP = Unit->getPreprocessor();
7457 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
7458 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00007459 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007460
Alp Toker2d57cea2014-05-17 04:53:25 +00007461 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007462 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007463 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007464
7465 // Check that the identifier is not one of the macro arguments.
7466 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00007467 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007468
Richard Smith20e883e2015-04-29 23:20:19 +00007469 MacroDirective *InnerMD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007470 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00007471 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007472
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007473 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007474}
7475
Richard Smith66a81862015-05-04 02:25:31 +00007476MacroDefinitionRecord *
7477cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, SourceLocation Loc,
7478 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007479 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007480 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007481
7482 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007483 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007484 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007485 Preprocessor &PP = Unit->getPreprocessor();
7486 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00007487 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007488 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7489 Token Tok;
7490 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00007491 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007492
7493 return checkForMacroInMacroDefinition(MI, Tok, TU);
7494}
7495
Guy Benyei11169dd2012-12-18 14:30:41 +00007496extern "C" {
7497
7498CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007499 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00007500}
7501
7502} // end: extern "C"
7503
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007504Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7505 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007506 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007507 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007508 if (Unit->isMainFileAST())
7509 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007510 return *this;
7511 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007512 } else {
7513 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007514 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007515 return *this;
7516}
7517
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007518Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7519 *this << FE->getName();
7520 return *this;
7521}
7522
7523Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7524 CXString cursorName = clang_getCursorDisplayName(cursor);
7525 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7526 clang_disposeString(cursorName);
7527 return *this;
7528}
7529
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007530Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7531 CXFile File;
7532 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007533 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007534 CXString FileName = clang_getFileName(File);
7535 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7536 clang_disposeString(FileName);
7537 return *this;
7538}
7539
7540Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7541 CXSourceLocation BLoc = clang_getRangeStart(range);
7542 CXSourceLocation ELoc = clang_getRangeEnd(range);
7543
7544 CXFile BFile;
7545 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007546 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007547
7548 CXFile EFile;
7549 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007550 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007551
7552 CXString BFileName = clang_getFileName(BFile);
7553 if (BFile == EFile) {
7554 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7555 BLine, BColumn, ELine, EColumn);
7556 } else {
7557 CXString EFileName = clang_getFileName(EFile);
7558 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7559 BLine, BColumn)
7560 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7561 ELine, EColumn);
7562 clang_disposeString(EFileName);
7563 }
7564 clang_disposeString(BFileName);
7565 return *this;
7566}
7567
7568Logger &cxindex::Logger::operator<<(CXString Str) {
7569 *this << clang_getCString(Str);
7570 return *this;
7571}
7572
7573Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7574 LogOS << Fmt;
7575 return *this;
7576}
7577
Chandler Carruth37ad2582014-06-27 15:14:39 +00007578static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7579
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007580cxindex::Logger::~Logger() {
Chandler Carruth37ad2582014-06-27 15:14:39 +00007581 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007582
7583 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7584
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007585 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007586 OS << "[libclang:" << Name << ':';
7587
Alp Toker1a86ad22014-07-06 06:24:00 +00007588#ifdef USE_DARWIN_THREADS
7589 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007590 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7591 OS << tid << ':';
7592#endif
7593
7594 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7595 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
Yaron Keren09fb7c62015-03-10 07:33:23 +00007596 OS << Msg << '\n';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007597
7598 if (Trace) {
Zachary Turner1fe2a8d2015-03-05 19:15:09 +00007599 llvm::sys::PrintStackTrace(OS);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007600 OS << "--------------------------------------------------\n";
7601 }
7602}