blob: a92892a580a27ffd7fa2b70d51ecd839ebf0d011 [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);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001946
Guy Benyei11169dd2012-12-18 14:30:41 +00001947private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001948 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001949 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1950 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001951 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1952 void AddStmt(const Stmt *S);
1953 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001954 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001955 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001956 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001957};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00001958} // end anonyous namespace
Guy Benyei11169dd2012-12-18 14:30:41 +00001959
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001960void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001961 // 'S' should always be non-null, since it comes from the
1962 // statement we are visiting.
1963 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1964}
1965
1966void
1967EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1968 if (Qualifier)
1969 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1970}
1971
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001972void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001973 if (S)
1974 WL.push_back(StmtVisit(S, Parent));
1975}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001976void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001977 if (D)
1978 WL.push_back(DeclVisit(D, Parent, isFirst));
1979}
1980void EnqueueVisitor::
1981 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1982 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001983 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001984}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001985void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001986 if (D)
1987 WL.push_back(MemberRefVisit(D, L, Parent));
1988}
1989void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1990 if (TI)
1991 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1992 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001993void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001994 unsigned size = WL.size();
Benjamin Kramer642f1732015-07-02 21:03:14 +00001995 for (const Stmt *SubStmt : S->children()) {
1996 AddStmt(SubStmt);
Guy Benyei11169dd2012-12-18 14:30:41 +00001997 }
1998 if (size == WL.size())
1999 return;
2000 // Now reverse the entries we just added. This will match the DFS
2001 // ordering performed by the worklist.
2002 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2003 std::reverse(I, E);
2004}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002005namespace {
2006class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
2007 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00002008 /// \brief Process clauses with list of variables.
2009 template <typename T>
2010 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002011public:
2012 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
2013#define OPENMP_CLAUSE(Name, Class) \
2014 void Visit##Class(const Class *C);
2015#include "clang/Basic/OpenMPKinds.def"
2016};
2017
Alexey Bataevaadd52e2014-02-13 05:29:23 +00002018void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
2019 Visitor->AddStmt(C->getCondition());
2020}
2021
Alexey Bataev3778b602014-07-17 07:32:53 +00002022void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
2023 Visitor->AddStmt(C->getCondition());
2024}
2025
Alexey Bataev568a8332014-03-06 06:15:19 +00002026void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
2027 Visitor->AddStmt(C->getNumThreads());
2028}
2029
Alexey Bataev62c87d22014-03-21 04:51:18 +00002030void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
2031 Visitor->AddStmt(C->getSafelen());
2032}
2033
Alexey Bataev66b15b52015-08-21 11:14:16 +00002034void OMPClauseEnqueue::VisitOMPSimdlenClause(const OMPSimdlenClause *C) {
2035 Visitor->AddStmt(C->getSimdlen());
2036}
2037
Alexander Musman8bd31e62014-05-27 15:12:19 +00002038void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
2039 Visitor->AddStmt(C->getNumForLoops());
2040}
2041
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002042void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00002043
Alexey Bataevbcbadb62014-05-06 06:04:14 +00002044void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
2045
Alexey Bataev56dafe82014-06-20 07:16:17 +00002046void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
2047 Visitor->AddStmt(C->getChunkSize());
Alexey Bataev040d5402015-05-12 08:35:28 +00002048 Visitor->AddStmt(C->getHelperChunkSize());
Alexey Bataev56dafe82014-06-20 07:16:17 +00002049}
2050
Alexey Bataev10e775f2015-07-30 11:36:16 +00002051void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *C) {
2052 Visitor->AddStmt(C->getNumForLoops());
2053}
Alexey Bataev142e1fc2014-06-20 09:44:06 +00002054
Alexey Bataev236070f2014-06-20 11:19:47 +00002055void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
2056
Alexey Bataev7aea99a2014-07-17 12:19:31 +00002057void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
2058
Alexey Bataev74ba3a52014-07-17 12:47:03 +00002059void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
2060
Alexey Bataevf98b00c2014-07-23 02:27:21 +00002061void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}
2062
Alexey Bataevdea47612014-07-23 07:46:59 +00002063void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {}
2064
Alexey Bataev67a4f222014-07-23 10:25:33 +00002065void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {}
2066
Alexey Bataev459dec02014-07-24 06:46:57 +00002067void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}
2068
Alexey Bataev82bad8b2014-07-24 08:55:34 +00002069void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
2070
Alexey Bataev346265e2015-09-25 10:37:12 +00002071void OMPClauseEnqueue::VisitOMPThreadsClause(const OMPThreadsClause *) {}
2072
Alexey Bataevd14d1e62015-09-28 06:39:35 +00002073void OMPClauseEnqueue::VisitOMPSIMDClause(const OMPSIMDClause *) {}
2074
Michael Wonge710d542015-08-07 16:16:36 +00002075void OMPClauseEnqueue::VisitOMPDeviceClause(const OMPDeviceClause *C) {
2076 Visitor->AddStmt(C->getDevice());
2077}
2078
Kelvin Li099bb8c2015-11-24 20:50:12 +00002079void OMPClauseEnqueue::VisitOMPNumTeamsClause(const OMPNumTeamsClause *C) {
2080 Visitor->AddStmt(C->getNumTeams());
2081}
2082
Kelvin Lia15fb1a2015-11-27 18:47:36 +00002083void OMPClauseEnqueue::VisitOMPThreadLimitClause(const OMPThreadLimitClause *C) {
2084 Visitor->AddStmt(C->getThreadLimit());
2085}
2086
Alexey Bataev756c1962013-09-24 03:17:45 +00002087template<typename T>
2088void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Alexey Bataev03b340a2014-10-21 03:16:40 +00002089 for (const auto *I : Node->varlists()) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00002090 Visitor->AddStmt(I);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002091 }
Alexey Bataev756c1962013-09-24 03:17:45 +00002092}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002093
2094void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002095 VisitOMPClauseList(C);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002096 for (const auto *E : C->private_copies()) {
2097 Visitor->AddStmt(E);
2098 }
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002099}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002100void OMPClauseEnqueue::VisitOMPFirstprivateClause(
2101 const OMPFirstprivateClause *C) {
2102 VisitOMPClauseList(C);
2103}
Alexander Musman1bb328c2014-06-04 13:06:39 +00002104void OMPClauseEnqueue::VisitOMPLastprivateClause(
2105 const OMPLastprivateClause *C) {
2106 VisitOMPClauseList(C);
Alexey Bataev38e89532015-04-16 04:54:05 +00002107 for (auto *E : C->private_copies()) {
2108 Visitor->AddStmt(E);
2109 }
2110 for (auto *E : C->source_exprs()) {
2111 Visitor->AddStmt(E);
2112 }
2113 for (auto *E : C->destination_exprs()) {
2114 Visitor->AddStmt(E);
2115 }
2116 for (auto *E : C->assignment_ops()) {
2117 Visitor->AddStmt(E);
2118 }
Alexander Musman1bb328c2014-06-04 13:06:39 +00002119}
Alexey Bataev758e55e2013-09-06 18:03:48 +00002120void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002121 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00002122}
Alexey Bataevc5e02582014-06-16 07:08:35 +00002123void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
2124 VisitOMPClauseList(C);
Alexey Bataevf24e7b12015-10-08 09:10:53 +00002125 for (auto *E : C->privates()) {
2126 Visitor->AddStmt(E);
2127 }
Alexey Bataev794ba0d2015-04-10 10:43:45 +00002128 for (auto *E : C->lhs_exprs()) {
2129 Visitor->AddStmt(E);
2130 }
2131 for (auto *E : C->rhs_exprs()) {
2132 Visitor->AddStmt(E);
2133 }
2134 for (auto *E : C->reduction_ops()) {
2135 Visitor->AddStmt(E);
2136 }
Alexey Bataevc5e02582014-06-16 07:08:35 +00002137}
Alexander Musman8dba6642014-04-22 13:09:42 +00002138void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2139 VisitOMPClauseList(C);
Alexey Bataevbd9fec12015-08-18 06:47:21 +00002140 for (const auto *E : C->privates()) {
2141 Visitor->AddStmt(E);
2142 }
Alexander Musman3276a272015-03-21 10:12:56 +00002143 for (const auto *E : C->inits()) {
2144 Visitor->AddStmt(E);
2145 }
2146 for (const auto *E : C->updates()) {
2147 Visitor->AddStmt(E);
2148 }
2149 for (const auto *E : C->finals()) {
2150 Visitor->AddStmt(E);
2151 }
Alexander Musman8dba6642014-04-22 13:09:42 +00002152 Visitor->AddStmt(C->getStep());
Alexander Musman3276a272015-03-21 10:12:56 +00002153 Visitor->AddStmt(C->getCalcStep());
Alexander Musman8dba6642014-04-22 13:09:42 +00002154}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002155void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2156 VisitOMPClauseList(C);
2157 Visitor->AddStmt(C->getAlignment());
2158}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002159void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2160 VisitOMPClauseList(C);
Alexey Bataevf56f98c2015-04-16 05:39:01 +00002161 for (auto *E : C->source_exprs()) {
2162 Visitor->AddStmt(E);
2163 }
2164 for (auto *E : C->destination_exprs()) {
2165 Visitor->AddStmt(E);
2166 }
2167 for (auto *E : C->assignment_ops()) {
2168 Visitor->AddStmt(E);
2169 }
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002170}
Alexey Bataevbae9a792014-06-27 10:37:06 +00002171void
2172OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
2173 VisitOMPClauseList(C);
Alexey Bataeva63048e2015-03-23 06:18:07 +00002174 for (auto *E : C->source_exprs()) {
2175 Visitor->AddStmt(E);
2176 }
2177 for (auto *E : C->destination_exprs()) {
2178 Visitor->AddStmt(E);
2179 }
2180 for (auto *E : C->assignment_ops()) {
2181 Visitor->AddStmt(E);
2182 }
Alexey Bataevbae9a792014-06-27 10:37:06 +00002183}
Alexey Bataev6125da92014-07-21 11:26:11 +00002184void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2185 VisitOMPClauseList(C);
2186}
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +00002187void OMPClauseEnqueue::VisitOMPDependClause(const OMPDependClause *C) {
2188 VisitOMPClauseList(C);
2189}
Kelvin Li0bff7af2015-11-23 05:32:03 +00002190void OMPClauseEnqueue::VisitOMPMapClause(const OMPMapClause *C) {
2191 VisitOMPClauseList(C);
2192}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002193}
Alexey Bataev756c1962013-09-24 03:17:45 +00002194
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002195void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2196 unsigned size = WL.size();
2197 OMPClauseEnqueue Visitor(this);
2198 Visitor.Visit(S);
2199 if (size == WL.size())
2200 return;
2201 // Now reverse the entries we just added. This will match the DFS
2202 // ordering performed by the worklist.
2203 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2204 std::reverse(I, E);
2205}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002206void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002207 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2208}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002209void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002210 AddDecl(B->getBlockDecl());
2211}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002212void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002213 EnqueueChildren(E);
2214 AddTypeLoc(E->getTypeSourceInfo());
2215}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002216void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
Pete Cooper57d3f142015-07-30 17:22:52 +00002217 for (auto &I : llvm::reverse(S->body()))
2218 AddStmt(I);
Guy Benyei11169dd2012-12-18 14:30:41 +00002219}
2220void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002221VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002222 AddStmt(S->getSubStmt());
2223 AddDeclarationNameInfo(S);
2224 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2225 AddNestedNameSpecifierLoc(QualifierLoc);
2226}
2227
2228void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002229VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002230 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2231 AddDeclarationNameInfo(E);
2232 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2233 AddNestedNameSpecifierLoc(QualifierLoc);
2234 if (!E->isImplicitAccess())
2235 AddStmt(E->getBase());
2236}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002237void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002238 // Enqueue the initializer , if any.
2239 AddStmt(E->getInitializer());
2240 // Enqueue the array size, if any.
2241 AddStmt(E->getArraySize());
2242 // Enqueue the allocated type.
2243 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2244 // Enqueue the placement arguments.
2245 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2246 AddStmt(E->getPlacementArg(I-1));
2247}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002248void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002249 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2250 AddStmt(CE->getArg(I-1));
2251 AddStmt(CE->getCallee());
2252 AddStmt(CE->getArg(0));
2253}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002254void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2255 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002256 // Visit the name of the type being destroyed.
2257 AddTypeLoc(E->getDestroyedTypeInfo());
2258 // Visit the scope type that looks disturbingly like the nested-name-specifier
2259 // but isn't.
2260 AddTypeLoc(E->getScopeTypeInfo());
2261 // Visit the nested-name-specifier.
2262 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2263 AddNestedNameSpecifierLoc(QualifierLoc);
2264 // Visit base expression.
2265 AddStmt(E->getBase());
2266}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002267void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2268 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002269 AddTypeLoc(E->getTypeSourceInfo());
2270}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002271void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2272 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002273 EnqueueChildren(E);
2274 AddTypeLoc(E->getTypeSourceInfo());
2275}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002276void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002277 EnqueueChildren(E);
2278 if (E->isTypeOperand())
2279 AddTypeLoc(E->getTypeOperandSourceInfo());
2280}
2281
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002282void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2283 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002284 EnqueueChildren(E);
2285 AddTypeLoc(E->getTypeSourceInfo());
2286}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002287void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002288 EnqueueChildren(E);
2289 if (E->isTypeOperand())
2290 AddTypeLoc(E->getTypeOperandSourceInfo());
2291}
2292
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002293void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002294 EnqueueChildren(S);
2295 AddDecl(S->getExceptionDecl());
2296}
2297
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002298void EnqueueVisitor::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002299 AddStmt(S->getBody());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002300 AddStmt(S->getRangeInit());
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002301 AddDecl(S->getLoopVariable());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002302}
2303
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002304void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002305 if (DR->hasExplicitTemplateArgs()) {
2306 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2307 }
2308 WL.push_back(DeclRefExprParts(DR, Parent));
2309}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002310void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2311 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002312 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2313 AddDeclarationNameInfo(E);
2314 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2315}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002316void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002317 unsigned size = WL.size();
2318 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002319 for (const auto *D : S->decls()) {
2320 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002321 isFirst = false;
2322 }
2323 if (size == WL.size())
2324 return;
2325 // Now reverse the entries we just added. This will match the DFS
2326 // ordering performed by the worklist.
2327 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2328 std::reverse(I, E);
2329}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002330void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002331 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002332 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002333 D = E->designators_rbegin(), DEnd = E->designators_rend();
2334 D != DEnd; ++D) {
2335 if (D->isFieldDesignator()) {
2336 if (FieldDecl *Field = D->getField())
2337 AddMemberRef(Field, D->getFieldLoc());
2338 continue;
2339 }
2340 if (D->isArrayDesignator()) {
2341 AddStmt(E->getArrayIndex(*D));
2342 continue;
2343 }
2344 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2345 AddStmt(E->getArrayRangeEnd(*D));
2346 AddStmt(E->getArrayRangeStart(*D));
2347 }
2348}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002349void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002350 EnqueueChildren(E);
2351 AddTypeLoc(E->getTypeInfoAsWritten());
2352}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002353void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002354 AddStmt(FS->getBody());
2355 AddStmt(FS->getInc());
2356 AddStmt(FS->getCond());
2357 AddDecl(FS->getConditionVariable());
2358 AddStmt(FS->getInit());
2359}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002360void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002361 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2362}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002363void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002364 AddStmt(If->getElse());
2365 AddStmt(If->getThen());
2366 AddStmt(If->getCond());
2367 AddDecl(If->getConditionVariable());
2368}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002369void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002370 // We care about the syntactic form of the initializer list, only.
2371 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2372 IE = Syntactic;
2373 EnqueueChildren(IE);
2374}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002375void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002376 WL.push_back(MemberExprParts(M, Parent));
2377
2378 // If the base of the member access expression is an implicit 'this', don't
2379 // visit it.
2380 // FIXME: If we ever want to show these implicit accesses, this will be
2381 // unfortunate. However, clang_getCursor() relies on this behavior.
Argyrios Kyrtzidis58d0e7a2015-03-13 04:40:07 +00002382 if (M->isImplicitAccess())
2383 return;
2384
2385 // Ignore base anonymous struct/union fields, otherwise they will shadow the
2386 // real field that that we are interested in.
2387 if (auto *SubME = dyn_cast<MemberExpr>(M->getBase())) {
2388 if (auto *FD = dyn_cast_or_null<FieldDecl>(SubME->getMemberDecl())) {
2389 if (FD->isAnonymousStructOrUnion()) {
2390 AddStmt(SubME->getBase());
2391 return;
2392 }
2393 }
2394 }
2395
2396 AddStmt(M->getBase());
Guy Benyei11169dd2012-12-18 14:30:41 +00002397}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002398void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002399 AddTypeLoc(E->getEncodedTypeSourceInfo());
2400}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002401void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002402 EnqueueChildren(M);
2403 AddTypeLoc(M->getClassReceiverTypeInfo());
2404}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002405void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002406 // Visit the components of the offsetof expression.
2407 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2408 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2409 const OffsetOfNode &Node = E->getComponent(I-1);
2410 switch (Node.getKind()) {
2411 case OffsetOfNode::Array:
2412 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2413 break;
2414 case OffsetOfNode::Field:
2415 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2416 break;
2417 case OffsetOfNode::Identifier:
2418 case OffsetOfNode::Base:
2419 continue;
2420 }
2421 }
2422 // Visit the type into which we're computing the offset.
2423 AddTypeLoc(E->getTypeSourceInfo());
2424}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002425void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002426 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2427 WL.push_back(OverloadExprParts(E, Parent));
2428}
2429void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002430 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002431 EnqueueChildren(E);
2432 if (E->isArgumentType())
2433 AddTypeLoc(E->getArgumentTypeInfo());
2434}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002435void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002436 EnqueueChildren(S);
2437}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002438void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002439 AddStmt(S->getBody());
2440 AddStmt(S->getCond());
2441 AddDecl(S->getConditionVariable());
2442}
2443
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002444void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002445 AddStmt(W->getBody());
2446 AddStmt(W->getCond());
2447 AddDecl(W->getConditionVariable());
2448}
2449
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002450void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002451 for (unsigned I = E->getNumArgs(); I > 0; --I)
2452 AddTypeLoc(E->getArg(I-1));
2453}
2454
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002455void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002456 AddTypeLoc(E->getQueriedTypeSourceInfo());
2457}
2458
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002459void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002460 EnqueueChildren(E);
2461}
2462
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002463void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002464 VisitOverloadExpr(U);
2465 if (!U->isImplicitAccess())
2466 AddStmt(U->getBase());
2467}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002468void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002469 AddStmt(E->getSubExpr());
2470 AddTypeLoc(E->getWrittenTypeInfo());
2471}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002472void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002473 WL.push_back(SizeOfPackExprParts(E, Parent));
2474}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002475void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002476 // If the opaque value has a source expression, just transparently
2477 // visit that. This is useful for (e.g.) pseudo-object expressions.
2478 if (Expr *SourceExpr = E->getSourceExpr())
2479 return Visit(SourceExpr);
2480}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002481void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002482 AddStmt(E->getBody());
2483 WL.push_back(LambdaExprParts(E, Parent));
2484}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002485void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002486 // Treat the expression like its syntactic form.
2487 Visit(E->getSyntacticForm());
2488}
2489
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002490void EnqueueVisitor::VisitOMPExecutableDirective(
2491 const OMPExecutableDirective *D) {
2492 EnqueueChildren(D);
2493 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2494 E = D->clauses().end();
2495 I != E; ++I)
2496 EnqueueChildren(*I);
2497}
2498
Alexander Musman3aaab662014-08-19 11:27:13 +00002499void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
2500 VisitOMPExecutableDirective(D);
2501}
2502
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002503void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2504 VisitOMPExecutableDirective(D);
2505}
2506
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002507void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002508 VisitOMPLoopDirective(D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002509}
2510
Alexey Bataevf29276e2014-06-18 04:14:57 +00002511void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002512 VisitOMPLoopDirective(D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002513}
2514
Alexander Musmanf82886e2014-09-18 05:12:34 +00002515void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
2516 VisitOMPLoopDirective(D);
2517}
2518
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002519void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2520 VisitOMPExecutableDirective(D);
2521}
2522
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002523void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2524 VisitOMPExecutableDirective(D);
2525}
2526
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002527void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2528 VisitOMPExecutableDirective(D);
2529}
2530
Alexander Musman80c22892014-07-17 08:54:58 +00002531void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2532 VisitOMPExecutableDirective(D);
2533}
2534
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002535void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2536 VisitOMPExecutableDirective(D);
2537 AddDeclarationNameInfo(D);
2538}
2539
Alexey Bataev4acb8592014-07-07 13:01:15 +00002540void
2541EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002542 VisitOMPLoopDirective(D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002543}
2544
Alexander Musmane4e893b2014-09-23 09:33:00 +00002545void EnqueueVisitor::VisitOMPParallelForSimdDirective(
2546 const OMPParallelForSimdDirective *D) {
2547 VisitOMPLoopDirective(D);
2548}
2549
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002550void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2551 const OMPParallelSectionsDirective *D) {
2552 VisitOMPExecutableDirective(D);
2553}
2554
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002555void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2556 VisitOMPExecutableDirective(D);
2557}
2558
Alexey Bataev68446b72014-07-18 07:47:19 +00002559void
2560EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2561 VisitOMPExecutableDirective(D);
2562}
2563
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002564void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2565 VisitOMPExecutableDirective(D);
2566}
2567
Alexey Bataev2df347a2014-07-18 10:17:07 +00002568void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2569 VisitOMPExecutableDirective(D);
2570}
2571
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002572void EnqueueVisitor::VisitOMPTaskgroupDirective(
2573 const OMPTaskgroupDirective *D) {
2574 VisitOMPExecutableDirective(D);
2575}
2576
Alexey Bataev6125da92014-07-21 11:26:11 +00002577void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2578 VisitOMPExecutableDirective(D);
2579}
2580
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002581void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2582 VisitOMPExecutableDirective(D);
2583}
2584
Alexey Bataev0162e452014-07-22 10:10:35 +00002585void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2586 VisitOMPExecutableDirective(D);
2587}
2588
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002589void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
2590 VisitOMPExecutableDirective(D);
2591}
2592
Michael Wong65f367f2015-07-21 13:44:28 +00002593void EnqueueVisitor::VisitOMPTargetDataDirective(const
2594 OMPTargetDataDirective *D) {
2595 VisitOMPExecutableDirective(D);
2596}
2597
Alexey Bataev13314bf2014-10-09 04:18:56 +00002598void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {
2599 VisitOMPExecutableDirective(D);
2600}
2601
Alexey Bataev6d4ed052015-07-01 06:57:41 +00002602void EnqueueVisitor::VisitOMPCancellationPointDirective(
2603 const OMPCancellationPointDirective *D) {
2604 VisitOMPExecutableDirective(D);
2605}
2606
Alexey Bataev80909872015-07-02 11:25:17 +00002607void EnqueueVisitor::VisitOMPCancelDirective(const OMPCancelDirective *D) {
2608 VisitOMPExecutableDirective(D);
2609}
2610
Alexey Bataev49f6e782015-12-01 04:18:41 +00002611void EnqueueVisitor::VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *D) {
2612 VisitOMPLoopDirective(D);
2613}
2614
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002615void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002616 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2617}
2618
2619bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2620 if (RegionOfInterest.isValid()) {
2621 SourceRange Range = getRawCursorExtent(C);
2622 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2623 return false;
2624 }
2625 return true;
2626}
2627
2628bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2629 while (!WL.empty()) {
2630 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002631 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002632
2633 // Set the Parent field, then back to its old value once we're done.
2634 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2635
2636 switch (LI.getKind()) {
2637 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002638 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002639 if (!D)
2640 continue;
2641
2642 // For now, perform default visitation for Decls.
2643 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2644 cast<DeclVisit>(&LI)->isFirst())))
2645 return true;
2646
2647 continue;
2648 }
2649 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2650 const ASTTemplateArgumentListInfo *ArgList =
2651 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2652 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2653 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2654 Arg != ArgEnd; ++Arg) {
2655 if (VisitTemplateArgumentLoc(*Arg))
2656 return true;
2657 }
2658 continue;
2659 }
2660 case VisitorJob::TypeLocVisitKind: {
2661 // Perform default visitation for TypeLocs.
2662 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2663 return true;
2664 continue;
2665 }
2666 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002667 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002668 if (LabelStmt *stmt = LS->getStmt()) {
2669 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2670 TU))) {
2671 return true;
2672 }
2673 }
2674 continue;
2675 }
2676
2677 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2678 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2679 if (VisitNestedNameSpecifierLoc(V->get()))
2680 return true;
2681 continue;
2682 }
2683
2684 case VisitorJob::DeclarationNameInfoVisitKind: {
2685 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2686 ->get()))
2687 return true;
2688 continue;
2689 }
2690 case VisitorJob::MemberRefVisitKind: {
2691 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2692 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2693 return true;
2694 continue;
2695 }
2696 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002697 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002698 if (!S)
2699 continue;
2700
2701 // Update the current cursor.
2702 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2703 if (!IsInRegionOfInterest(Cursor))
2704 continue;
2705 switch (Visitor(Cursor, Parent, ClientData)) {
2706 case CXChildVisit_Break: return true;
2707 case CXChildVisit_Continue: break;
2708 case CXChildVisit_Recurse:
2709 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002710 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002711 EnqueueWorkList(WL, S);
2712 break;
2713 }
2714 continue;
2715 }
2716 case VisitorJob::MemberExprPartsKind: {
2717 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002718 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002719
2720 // Visit the nested-name-specifier
2721 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2722 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2723 return true;
2724
2725 // Visit the declaration name.
2726 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2727 return true;
2728
2729 // Visit the explicitly-specified template arguments, if any.
2730 if (M->hasExplicitTemplateArgs()) {
2731 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2732 *ArgEnd = Arg + M->getNumTemplateArgs();
2733 Arg != ArgEnd; ++Arg) {
2734 if (VisitTemplateArgumentLoc(*Arg))
2735 return true;
2736 }
2737 }
2738 continue;
2739 }
2740 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002741 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002742 // Visit nested-name-specifier, if present.
2743 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2744 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2745 return true;
2746 // Visit declaration name.
2747 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2748 return true;
2749 continue;
2750 }
2751 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002752 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002753 // Visit the nested-name-specifier.
2754 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2755 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2756 return true;
2757 // Visit the declaration name.
2758 if (VisitDeclarationNameInfo(O->getNameInfo()))
2759 return true;
2760 // Visit the overloaded declaration reference.
2761 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2762 return true;
2763 continue;
2764 }
2765 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002766 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002767 NamedDecl *Pack = E->getPack();
2768 if (isa<TemplateTypeParmDecl>(Pack)) {
2769 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2770 E->getPackLoc(), TU)))
2771 return true;
2772
2773 continue;
2774 }
2775
2776 if (isa<TemplateTemplateParmDecl>(Pack)) {
2777 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2778 E->getPackLoc(), TU)))
2779 return true;
2780
2781 continue;
2782 }
2783
2784 // Non-type template parameter packs and function parameter packs are
2785 // treated like DeclRefExpr cursors.
2786 continue;
2787 }
2788
2789 case VisitorJob::LambdaExprPartsKind: {
2790 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002791 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002792 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2793 CEnd = E->explicit_capture_end();
2794 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002795 // FIXME: Lambda init-captures.
2796 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002797 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002798
Guy Benyei11169dd2012-12-18 14:30:41 +00002799 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2800 C->getLocation(),
2801 TU)))
2802 return true;
2803 }
2804
2805 // Visit parameters and return type, if present.
2806 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2807 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2808 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2809 // Visit the whole type.
2810 if (Visit(TL))
2811 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002812 } else if (FunctionProtoTypeLoc Proto =
2813 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002814 if (E->hasExplicitParameters()) {
2815 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002816 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2817 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002818 return true;
2819 } else {
2820 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002821 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002822 return true;
2823 }
2824 }
2825 }
2826 break;
2827 }
2828
2829 case VisitorJob::PostChildrenVisitKind:
2830 if (PostChildrenVisitor(Parent, ClientData))
2831 return true;
2832 break;
2833 }
2834 }
2835 return false;
2836}
2837
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002838bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002839 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002840 if (!WorkListFreeList.empty()) {
2841 WL = WorkListFreeList.back();
2842 WL->clear();
2843 WorkListFreeList.pop_back();
2844 }
2845 else {
2846 WL = new VisitorWorkList();
2847 WorkListCache.push_back(WL);
2848 }
2849 EnqueueWorkList(*WL, S);
2850 bool result = RunVisitorWorkList(*WL);
2851 WorkListFreeList.push_back(WL);
2852 return result;
2853}
2854
2855namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002856typedef SmallVector<SourceRange, 4> RefNamePieces;
Craig Topper69186e72014-06-08 08:38:04 +00002857RefNamePieces
2858buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
Craig Toppere335f252015-10-04 04:53:55 +00002859 const DeclarationNameInfo &NI, SourceRange QLoc,
Craig Topper69186e72014-06-08 08:38:04 +00002860 const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002861 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2862 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2863 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2864
2865 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2866
2867 RefNamePieces Pieces;
2868
2869 if (WantQualifier && QLoc.isValid())
2870 Pieces.push_back(QLoc);
2871
2872 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2873 Pieces.push_back(NI.getLoc());
2874
2875 if (WantTemplateArgs && TemplateArgs)
2876 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2877 TemplateArgs->RAngleLoc));
2878
2879 if (Kind == DeclarationName::CXXOperatorName) {
2880 Pieces.push_back(SourceLocation::getFromRawEncoding(
2881 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2882 Pieces.push_back(SourceLocation::getFromRawEncoding(
2883 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2884 }
2885
2886 if (WantSinglePiece) {
2887 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2888 Pieces.clear();
2889 Pieces.push_back(R);
2890 }
2891
2892 return Pieces;
2893}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002894}
Guy Benyei11169dd2012-12-18 14:30:41 +00002895
2896//===----------------------------------------------------------------------===//
2897// Misc. API hooks.
2898//===----------------------------------------------------------------------===//
2899
Chad Rosier05c71aa2013-03-27 18:28:23 +00002900static void fatal_error_handler(void *user_data, const std::string& reason,
2901 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002902 // Write the result out to stderr avoiding errs() because raw_ostreams can
2903 // call report_fatal_error.
2904 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2905 ::abort();
2906}
2907
Chandler Carruth66660742014-06-27 16:37:27 +00002908namespace {
2909struct RegisterFatalErrorHandler {
2910 RegisterFatalErrorHandler() {
2911 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2912 }
2913};
2914}
2915
2916static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
2917
Guy Benyei11169dd2012-12-18 14:30:41 +00002918extern "C" {
2919CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2920 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002921 // We use crash recovery to make some of our APIs more reliable, implicitly
2922 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002923 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2924 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002925
Chandler Carruth66660742014-06-27 16:37:27 +00002926 // Look through the managed static to trigger construction of the managed
2927 // static which registers our fatal error handler. This ensures it is only
2928 // registered once.
2929 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00002930
Adrian Prantlbc068582015-07-08 01:00:30 +00002931 // Initialize targets for clang module support.
2932 llvm::InitializeAllTargets();
2933 llvm::InitializeAllTargetMCs();
2934 llvm::InitializeAllAsmPrinters();
2935 llvm::InitializeAllAsmParsers();
2936
Adrian Prantlfb2398d2015-07-17 01:19:54 +00002937 CIndexer *CIdxr = new CIndexer();
2938
Guy Benyei11169dd2012-12-18 14:30:41 +00002939 if (excludeDeclarationsFromPCH)
2940 CIdxr->setOnlyLocalDecls();
2941 if (displayDiagnostics)
2942 CIdxr->setDisplayDiagnostics();
2943
2944 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2945 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2946 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2947 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2948 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2949 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2950
2951 return CIdxr;
2952}
2953
2954void clang_disposeIndex(CXIndex CIdx) {
2955 if (CIdx)
2956 delete static_cast<CIndexer *>(CIdx);
2957}
2958
2959void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2960 if (CIdx)
2961 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2962}
2963
2964unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2965 if (CIdx)
2966 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2967 return 0;
2968}
2969
2970void clang_toggleCrashRecovery(unsigned isEnabled) {
2971 if (isEnabled)
2972 llvm::CrashRecoveryContext::Enable();
2973 else
2974 llvm::CrashRecoveryContext::Disable();
2975}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002976
Guy Benyei11169dd2012-12-18 14:30:41 +00002977CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2978 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002979 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002980 enum CXErrorCode Result =
2981 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002982 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002983 assert((TU && Result == CXError_Success) ||
2984 (!TU && Result != CXError_Success));
2985 return TU;
2986}
2987
2988enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2989 const char *ast_filename,
2990 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002991 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002992 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002993
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002994 if (!CIdx || !ast_filename || !out_TU)
2995 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002996
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002997 LOG_FUNC_SECTION {
2998 *Log << ast_filename;
2999 }
3000
Guy Benyei11169dd2012-12-18 14:30:41 +00003001 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3002 FileSystemOptions FileSystemOpts;
3003
Justin Bognerd512c1e2014-10-15 00:33:06 +00003004 IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
3005 CompilerInstance::createDiagnostics(new DiagnosticOptions());
David Blaikie6f7382d2014-08-10 19:08:04 +00003006 std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
Adrian Prantlfb2398d2015-07-17 01:19:54 +00003007 ast_filename, CXXIdx->getPCHContainerOperations()->getRawReader(), Diags,
Adrian Prantl6b21ab22015-08-27 19:46:20 +00003008 FileSystemOpts, /*UseDebugInfo=*/false,
3009 CXXIdx->getOnlyLocalDecls(), None,
David Blaikie6f7382d2014-08-10 19:08:04 +00003010 /*CaptureDiagnostics=*/true,
3011 /*AllowPCHWithCompilerErrors=*/true,
3012 /*UserFilesAreVolatile=*/true);
3013 *out_TU = MakeCXTranslationUnit(CXXIdx, AU.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003014 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003015}
3016
3017unsigned clang_defaultEditingTranslationUnitOptions() {
3018 return CXTranslationUnit_PrecompiledPreamble |
3019 CXTranslationUnit_CacheCompletionResults;
3020}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003021
Guy Benyei11169dd2012-12-18 14:30:41 +00003022CXTranslationUnit
3023clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
3024 const char *source_filename,
3025 int num_command_line_args,
3026 const char * const *command_line_args,
3027 unsigned num_unsaved_files,
3028 struct CXUnsavedFile *unsaved_files) {
3029 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
3030 return clang_parseTranslationUnit(CIdx, source_filename,
3031 command_line_args, num_command_line_args,
3032 unsaved_files, num_unsaved_files,
3033 Options);
3034}
3035
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003036static CXErrorCode
3037clang_parseTranslationUnit_Impl(CXIndex CIdx, const char *source_filename,
3038 const char *const *command_line_args,
3039 int num_command_line_args,
3040 ArrayRef<CXUnsavedFile> unsaved_files,
3041 unsigned options, CXTranslationUnit *out_TU) {
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003042 // Set up the initial return values.
3043 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00003044 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003045
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003046 // Check arguments.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003047 if (!CIdx || !out_TU)
3048 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003049
Guy Benyei11169dd2012-12-18 14:30:41 +00003050 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3051
3052 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3053 setThreadBackgroundPriority();
3054
3055 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
3056 // FIXME: Add a flag for modules.
3057 TranslationUnitKind TUKind
3058 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00003059 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00003060 = options & CXTranslationUnit_CacheCompletionResults;
3061 bool IncludeBriefCommentsInCodeCompletion
3062 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
3063 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
3064 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
3065
3066 // Configure the diagnostics.
3067 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00003068 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00003069
3070 // Recover resources if we crash before exiting this function.
3071 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
3072 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00003073 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00003074
Ahmed Charlesb8984322014-03-07 20:03:18 +00003075 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3076 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003077
3078 // Recover resources if we crash before exiting this function.
3079 llvm::CrashRecoveryContextCleanupRegistrar<
3080 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3081
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003082 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003083 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003084 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003085 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003086 }
3087
Ahmed Charlesb8984322014-03-07 20:03:18 +00003088 std::unique_ptr<std::vector<const char *>> Args(
3089 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003090
3091 // Recover resources if we crash before exiting this method.
3092 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
3093 ArgsCleanup(Args.get());
3094
3095 // Since the Clang C library is primarily used by batch tools dealing with
3096 // (often very broken) source code, where spell-checking can have a
3097 // significant negative impact on performance (particularly when
3098 // precompiled headers are involved), we disable it by default.
3099 // Only do this if we haven't found a spell-checking-related argument.
3100 bool FoundSpellCheckingArgument = false;
3101 for (int I = 0; I != num_command_line_args; ++I) {
3102 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
3103 strcmp(command_line_args[I], "-fspell-checking") == 0) {
3104 FoundSpellCheckingArgument = true;
3105 break;
3106 }
3107 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003108 Args->insert(Args->end(), command_line_args,
3109 command_line_args + num_command_line_args);
3110
Benjamin Kramerc02670e2015-11-18 16:14:27 +00003111 if (!FoundSpellCheckingArgument)
3112 Args->insert(Args->begin() + 1, "-fno-spell-checking");
3113
Guy Benyei11169dd2012-12-18 14:30:41 +00003114 // The 'source_filename' argument is optional. If the caller does not
3115 // specify it then it is assumed that the source file is specified
3116 // in the actual argument list.
3117 // Put the source file after command_line_args otherwise if '-x' flag is
3118 // present it will be unused.
3119 if (source_filename)
3120 Args->push_back(source_filename);
3121
3122 // Do we need the detailed preprocessing record?
3123 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
3124 Args->push_back("-Xclang");
3125 Args->push_back("-detailed-preprocessing-record");
3126 }
3127
3128 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00003129 std::unique_ptr<ASTUnit> ErrUnit;
3130 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003131 Args->data(), Args->data() + Args->size(),
3132 CXXIdx->getPCHContainerOperations(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00003133 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
3134 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
3135 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
3136 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
3137 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
Argyrios Kyrtzidisa3e2ff12015-11-20 03:36:21 +00003138 /*UserFilesAreVolatile=*/true, ForSerialization,
3139 CXXIdx->getPCHContainerOperations()->getRawReader().getFormat(),
3140 &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00003141
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003142 // Early failures in LoadFromCommandLine may return with ErrUnit unset.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003143 if (!Unit && !ErrUnit)
3144 return CXError_ASTReadError;
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003145
Guy Benyei11169dd2012-12-18 14:30:41 +00003146 if (NumErrors != Diags->getClient()->getNumErrors()) {
3147 // Make sure to check that 'Unit' is non-NULL.
3148 if (CXXIdx->getDisplayDiagnostics())
3149 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
3150 }
3151
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003152 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get()))
3153 return CXError_ASTReadError;
3154
3155 *out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
3156 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003157}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003158
3159CXTranslationUnit
3160clang_parseTranslationUnit(CXIndex CIdx,
3161 const char *source_filename,
3162 const char *const *command_line_args,
3163 int num_command_line_args,
3164 struct CXUnsavedFile *unsaved_files,
3165 unsigned num_unsaved_files,
3166 unsigned options) {
3167 CXTranslationUnit TU;
3168 enum CXErrorCode Result = clang_parseTranslationUnit2(
3169 CIdx, source_filename, command_line_args, num_command_line_args,
3170 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00003171 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003172 assert((TU && Result == CXError_Success) ||
3173 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003174 return TU;
3175}
3176
3177enum CXErrorCode clang_parseTranslationUnit2(
Benjamin Kramerc02670e2015-11-18 16:14:27 +00003178 CXIndex CIdx, const char *source_filename,
3179 const char *const *command_line_args, int num_command_line_args,
3180 struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
3181 unsigned options, CXTranslationUnit *out_TU) {
3182 SmallVector<const char *, 4> Args;
3183 Args.push_back("clang");
3184 Args.append(command_line_args, command_line_args + num_command_line_args);
3185 return clang_parseTranslationUnit2FullArgv(
3186 CIdx, source_filename, Args.data(), Args.size(), unsaved_files,
3187 num_unsaved_files, options, out_TU);
3188}
3189
3190enum CXErrorCode clang_parseTranslationUnit2FullArgv(
3191 CXIndex CIdx, const char *source_filename,
3192 const char *const *command_line_args, int num_command_line_args,
3193 struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
3194 unsigned options, CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003195 LOG_FUNC_SECTION {
3196 *Log << source_filename << ": ";
3197 for (int i = 0; i != num_command_line_args; ++i)
3198 *Log << command_line_args[i] << " ";
3199 }
3200
Alp Toker9d85b182014-07-07 01:23:14 +00003201 if (num_unsaved_files && !unsaved_files)
3202 return CXError_InvalidArguments;
3203
Alp Toker5c532982014-07-07 22:42:03 +00003204 CXErrorCode result = CXError_Failure;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003205 auto ParseTranslationUnitImpl = [=, &result] {
3206 result = clang_parseTranslationUnit_Impl(
3207 CIdx, source_filename, command_line_args, num_command_line_args,
3208 llvm::makeArrayRef(unsaved_files, num_unsaved_files), options, out_TU);
3209 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003210 llvm::CrashRecoveryContext CRC;
3211
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003212 if (!RunSafely(CRC, ParseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003213 fprintf(stderr, "libclang: crash detected during parsing: {\n");
3214 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3215 fprintf(stderr, " 'command_line_args' : [");
3216 for (int i = 0; i != num_command_line_args; ++i) {
3217 if (i)
3218 fprintf(stderr, ", ");
3219 fprintf(stderr, "'%s'", command_line_args[i]);
3220 }
3221 fprintf(stderr, "],\n");
3222 fprintf(stderr, " 'unsaved_files' : [");
3223 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3224 if (i)
3225 fprintf(stderr, ", ");
3226 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3227 unsaved_files[i].Length);
3228 }
3229 fprintf(stderr, "],\n");
3230 fprintf(stderr, " 'options' : %d,\n", options);
3231 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003232
3233 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003234 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003235 if (CXTranslationUnit *TU = out_TU)
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003236 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003237 }
Alp Toker5c532982014-07-07 22:42:03 +00003238
3239 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003240}
3241
3242unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
3243 return CXSaveTranslationUnit_None;
3244}
3245
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003246static CXSaveError clang_saveTranslationUnit_Impl(CXTranslationUnit TU,
3247 const char *FileName,
3248 unsigned options) {
3249 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003250 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3251 setThreadBackgroundPriority();
3252
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003253 bool hadError = cxtu::getASTUnit(TU)->Save(FileName);
3254 return hadError ? CXSaveError_Unknown : CXSaveError_None;
Guy Benyei11169dd2012-12-18 14:30:41 +00003255}
3256
3257int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3258 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003259 LOG_FUNC_SECTION {
3260 *Log << TU << ' ' << FileName;
3261 }
3262
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003263 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003264 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003265 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003266 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003267
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003268 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003269 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3270 if (!CXXUnit->hasSema())
3271 return CXSaveError_InvalidTU;
3272
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003273 CXSaveError result;
3274 auto SaveTranslationUnitImpl = [=, &result]() {
3275 result = clang_saveTranslationUnit_Impl(TU, FileName, options);
3276 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003277
3278 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3279 getenv("LIBCLANG_NOTHREADS")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003280 SaveTranslationUnitImpl();
Guy Benyei11169dd2012-12-18 14:30:41 +00003281
3282 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3283 PrintLibclangResourceUsage(TU);
3284
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003285 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003286 }
3287
3288 // We have an AST that has invalid nodes due to compiler errors.
3289 // Use a crash recovery thread for protection.
3290
3291 llvm::CrashRecoveryContext CRC;
3292
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003293 if (!RunSafely(CRC, SaveTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003294 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3295 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3296 fprintf(stderr, " 'options' : %d,\n", options);
3297 fprintf(stderr, "}\n");
3298
3299 return CXSaveError_Unknown;
3300
3301 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3302 PrintLibclangResourceUsage(TU);
3303 }
3304
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003305 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003306}
3307
3308void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3309 if (CTUnit) {
3310 // If the translation unit has been marked as unsafe to free, just discard
3311 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003312 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3313 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003314 return;
3315
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003316 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003317 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003318 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3319 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003320 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003321 delete CTUnit;
3322 }
3323}
3324
3325unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3326 return CXReparse_None;
3327}
3328
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003329static CXErrorCode
3330clang_reparseTranslationUnit_Impl(CXTranslationUnit TU,
3331 ArrayRef<CXUnsavedFile> unsaved_files,
3332 unsigned options) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003333 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003334 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003335 LOG_BAD_TU(TU);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003336 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003337 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003338
3339 // Reset the associated diagnostics.
3340 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003341 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003342
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003343 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003344 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3345 setThreadBackgroundPriority();
3346
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003347 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003348 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003349
3350 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3351 new std::vector<ASTUnit::RemappedFile>());
3352
Guy Benyei11169dd2012-12-18 14:30:41 +00003353 // Recover resources if we crash before exiting this function.
3354 llvm::CrashRecoveryContextCleanupRegistrar<
3355 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003356
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003357 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003358 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003359 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003360 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003361 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003362
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003363 if (!CXXUnit->Reparse(CXXIdx->getPCHContainerOperations(),
3364 *RemappedFiles.get()))
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003365 return CXError_Success;
3366 if (isASTReadError(CXXUnit))
3367 return CXError_ASTReadError;
3368 return CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003369}
3370
3371int clang_reparseTranslationUnit(CXTranslationUnit TU,
3372 unsigned num_unsaved_files,
3373 struct CXUnsavedFile *unsaved_files,
3374 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003375 LOG_FUNC_SECTION {
3376 *Log << TU;
3377 }
3378
Alp Toker9d85b182014-07-07 01:23:14 +00003379 if (num_unsaved_files && !unsaved_files)
3380 return CXError_InvalidArguments;
3381
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003382 CXErrorCode result;
3383 auto ReparseTranslationUnitImpl = [=, &result]() {
3384 result = clang_reparseTranslationUnit_Impl(
3385 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options);
3386 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003387
3388 if (getenv("LIBCLANG_NOTHREADS")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003389 ReparseTranslationUnitImpl();
Alp Toker5c532982014-07-07 22:42:03 +00003390 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003391 }
3392
3393 llvm::CrashRecoveryContext CRC;
3394
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003395 if (!RunSafely(CRC, ReparseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003396 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003397 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003398 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003399 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3400 PrintLibclangResourceUsage(TU);
3401
Alp Toker5c532982014-07-07 22:42:03 +00003402 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003403}
3404
3405
3406CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003407 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003408 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003409 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003410 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003411
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003412 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003413 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003414}
3415
3416CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003417 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003418 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003419 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003420 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003421
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003422 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003423 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3424}
3425
3426} // end: extern "C"
3427
3428//===----------------------------------------------------------------------===//
3429// CXFile Operations.
3430//===----------------------------------------------------------------------===//
3431
3432extern "C" {
3433CXString clang_getFileName(CXFile SFile) {
3434 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003435 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003436
3437 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003438 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003439}
3440
3441time_t clang_getFileTime(CXFile SFile) {
3442 if (!SFile)
3443 return 0;
3444
3445 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3446 return FEnt->getModificationTime();
3447}
3448
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003449CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003450 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003451 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003452 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003453 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003454
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003455 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003456
3457 FileManager &FMgr = CXXUnit->getFileManager();
3458 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3459}
3460
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003461unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3462 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003463 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003464 LOG_BAD_TU(TU);
3465 return 0;
3466 }
3467
3468 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003469 return 0;
3470
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003471 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003472 FileEntry *FEnt = static_cast<FileEntry *>(file);
3473 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3474 .isFileMultipleIncludeGuarded(FEnt);
3475}
3476
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003477int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3478 if (!file || !outID)
3479 return 1;
3480
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003481 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003482 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3483 outID->data[0] = ID.getDevice();
3484 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003485 outID->data[2] = FEnt->getModificationTime();
3486 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003487}
3488
Argyrios Kyrtzidisac3997e2014-08-16 00:26:19 +00003489int clang_File_isEqual(CXFile file1, CXFile file2) {
3490 if (file1 == file2)
3491 return true;
3492
3493 if (!file1 || !file2)
3494 return false;
3495
3496 FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
3497 FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
3498 return FEnt1->getUniqueID() == FEnt2->getUniqueID();
3499}
3500
Guy Benyei11169dd2012-12-18 14:30:41 +00003501} // end: extern "C"
3502
3503//===----------------------------------------------------------------------===//
3504// CXCursor Operations.
3505//===----------------------------------------------------------------------===//
3506
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003507static const Decl *getDeclFromExpr(const Stmt *E) {
3508 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003509 return getDeclFromExpr(CE->getSubExpr());
3510
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003511 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003512 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003513 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003514 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003515 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003516 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003517 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003518 if (PRE->isExplicitProperty())
3519 return PRE->getExplicitProperty();
3520 // It could be messaging both getter and setter as in:
3521 // ++myobj.myprop;
3522 // in which case prefer to associate the setter since it is less obvious
3523 // from inspecting the source that the setter is going to get called.
3524 if (PRE->isMessagingSetter())
3525 return PRE->getImplicitPropertySetter();
3526 return PRE->getImplicitPropertyGetter();
3527 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003528 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003529 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003530 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003531 if (Expr *Src = OVE->getSourceExpr())
3532 return getDeclFromExpr(Src);
3533
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003534 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003535 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003536 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003537 if (!CE->isElidable())
3538 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003539 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003540 return OME->getMethodDecl();
3541
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003542 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003543 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003544 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003545 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3546 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003547 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003548 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3549 isa<ParmVarDecl>(SizeOfPack->getPack()))
3550 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003551
3552 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003553}
3554
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003555static SourceLocation getLocationFromExpr(const Expr *E) {
3556 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003557 return getLocationFromExpr(CE->getSubExpr());
3558
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003559 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003560 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003561 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003562 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003563 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003564 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003565 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003566 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003567 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003568 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003569 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003570 return PropRef->getLocation();
3571
3572 return E->getLocStart();
3573}
3574
Aaron Ballmana85d3f82015-11-12 15:25:06 +00003575static std::string getMangledStructor(std::unique_ptr<MangleContext> &M,
3576 std::unique_ptr<llvm::DataLayout> &DL,
3577 const NamedDecl *ND,
3578 unsigned StructorType) {
3579 std::string FrontendBuf;
3580 llvm::raw_string_ostream FOS(FrontendBuf);
3581
3582 if (const auto *CD = dyn_cast_or_null<CXXConstructorDecl>(ND))
3583 M->mangleCXXCtor(CD, static_cast<CXXCtorType>(StructorType), FOS);
3584 else if (const auto *DD = dyn_cast_or_null<CXXDestructorDecl>(ND))
3585 M->mangleCXXDtor(DD, static_cast<CXXDtorType>(StructorType), FOS);
3586
3587 std::string BackendBuf;
3588 llvm::raw_string_ostream BOS(BackendBuf);
3589
3590 llvm::Mangler::getNameWithPrefix(BOS, llvm::Twine(FOS.str()), *DL);
3591
3592 return BOS.str();
3593}
3594
Guy Benyei11169dd2012-12-18 14:30:41 +00003595extern "C" {
3596
3597unsigned clang_visitChildren(CXCursor parent,
3598 CXCursorVisitor visitor,
3599 CXClientData client_data) {
3600 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3601 /*VisitPreprocessorLast=*/false);
3602 return CursorVis.VisitChildren(parent);
3603}
3604
3605#ifndef __has_feature
3606#define __has_feature(x) 0
3607#endif
3608#if __has_feature(blocks)
3609typedef enum CXChildVisitResult
3610 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3611
3612static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3613 CXClientData client_data) {
3614 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3615 return block(cursor, parent);
3616}
3617#else
3618// If we are compiled with a compiler that doesn't have native blocks support,
3619// define and call the block manually, so the
3620typedef struct _CXChildVisitResult
3621{
3622 void *isa;
3623 int flags;
3624 int reserved;
3625 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3626 CXCursor);
3627} *CXCursorVisitorBlock;
3628
3629static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3630 CXClientData client_data) {
3631 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3632 return block->invoke(block, cursor, parent);
3633}
3634#endif
3635
3636
3637unsigned clang_visitChildrenWithBlock(CXCursor parent,
3638 CXCursorVisitorBlock block) {
3639 return clang_visitChildren(parent, visitWithBlock, block);
3640}
3641
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003642static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003643 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003644 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003645
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003646 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003647 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003648 if (const ObjCPropertyImplDecl *PropImpl =
3649 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003650 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003651 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003652
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003653 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003654 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003655 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003656
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003657 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003658 }
3659
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003660 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003661 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003662
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003663 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003664 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3665 // and returns different names. NamedDecl returns the class name and
3666 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003667 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003668
3669 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003670 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003671
3672 SmallString<1024> S;
3673 llvm::raw_svector_ostream os(S);
3674 ND->printName(os);
3675
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003676 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003677}
3678
3679CXString clang_getCursorSpelling(CXCursor C) {
3680 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003681 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003682
3683 if (clang_isReference(C.kind)) {
3684 switch (C.kind) {
3685 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003686 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003687 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003688 }
3689 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003690 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003691 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003692 }
3693 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003694 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003695 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003696 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003697 }
3698 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003699 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003700 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003701 }
3702 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003703 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003704 assert(Type && "Missing type decl");
3705
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003706 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003707 getAsString());
3708 }
3709 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003710 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003711 assert(Template && "Missing template decl");
3712
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003713 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003714 }
3715
3716 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003717 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003718 assert(NS && "Missing namespace decl");
3719
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003720 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003721 }
3722
3723 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003724 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003725 assert(Field && "Missing member decl");
3726
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003727 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003728 }
3729
3730 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003731 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003732 assert(Label && "Missing label");
3733
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003734 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003735 }
3736
3737 case CXCursor_OverloadedDeclRef: {
3738 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003739 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3740 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003741 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003742 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003743 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003744 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003745 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003746 OverloadedTemplateStorage *Ovl
3747 = Storage.get<OverloadedTemplateStorage*>();
3748 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003749 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003750 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003751 }
3752
3753 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003754 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003755 assert(Var && "Missing variable decl");
3756
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003757 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003758 }
3759
3760 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003761 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003762 }
3763 }
3764
3765 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003766 const Expr *E = getCursorExpr(C);
3767
3768 if (C.kind == CXCursor_ObjCStringLiteral ||
3769 C.kind == CXCursor_StringLiteral) {
3770 const StringLiteral *SLit;
3771 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3772 SLit = OSL->getString();
3773 } else {
3774 SLit = cast<StringLiteral>(E);
3775 }
3776 SmallString<256> Buf;
3777 llvm::raw_svector_ostream OS(Buf);
3778 SLit->outputString(OS);
3779 return cxstring::createDup(OS.str());
3780 }
3781
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003782 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003783 if (D)
3784 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003785 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003786 }
3787
3788 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003789 const Stmt *S = getCursorStmt(C);
3790 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003791 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003792
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003793 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003794 }
3795
3796 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003797 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003798 ->getNameStart());
3799
3800 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003801 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003802 ->getNameStart());
3803
3804 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003805 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003806
3807 if (clang_isDeclaration(C.kind))
3808 return getDeclSpelling(getCursorDecl(C));
3809
3810 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003811 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003812 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003813 }
3814
3815 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003816 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003817 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003818 }
3819
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003820 if (C.kind == CXCursor_PackedAttr) {
3821 return cxstring::createRef("packed");
3822 }
3823
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00003824 if (C.kind == CXCursor_VisibilityAttr) {
3825 const VisibilityAttr *AA = cast<VisibilityAttr>(cxcursor::getCursorAttr(C));
3826 switch (AA->getVisibility()) {
3827 case VisibilityAttr::VisibilityType::Default:
3828 return cxstring::createRef("default");
3829 case VisibilityAttr::VisibilityType::Hidden:
3830 return cxstring::createRef("hidden");
3831 case VisibilityAttr::VisibilityType::Protected:
3832 return cxstring::createRef("protected");
3833 }
3834 llvm_unreachable("unknown visibility type");
3835 }
3836
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003837 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003838}
3839
3840CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3841 unsigned pieceIndex,
3842 unsigned options) {
3843 if (clang_Cursor_isNull(C))
3844 return clang_getNullRange();
3845
3846 ASTContext &Ctx = getCursorContext(C);
3847
3848 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003849 const Stmt *S = getCursorStmt(C);
3850 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003851 if (pieceIndex > 0)
3852 return clang_getNullRange();
3853 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3854 }
3855
3856 return clang_getNullRange();
3857 }
3858
3859 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003860 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003861 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3862 if (pieceIndex >= ME->getNumSelectorLocs())
3863 return clang_getNullRange();
3864 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3865 }
3866 }
3867
3868 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3869 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003870 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003871 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3872 if (pieceIndex >= MD->getNumSelectorLocs())
3873 return clang_getNullRange();
3874 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3875 }
3876 }
3877
3878 if (C.kind == CXCursor_ObjCCategoryDecl ||
3879 C.kind == CXCursor_ObjCCategoryImplDecl) {
3880 if (pieceIndex > 0)
3881 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003882 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003883 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3884 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003885 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003886 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3887 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3888 }
3889
3890 if (C.kind == CXCursor_ModuleImportDecl) {
3891 if (pieceIndex > 0)
3892 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003893 if (const ImportDecl *ImportD =
3894 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003895 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3896 if (!Locs.empty())
3897 return cxloc::translateSourceRange(Ctx,
3898 SourceRange(Locs.front(), Locs.back()));
3899 }
3900 return clang_getNullRange();
3901 }
3902
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00003903 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
3904 C.kind == CXCursor_ConversionFunction) {
3905 if (pieceIndex > 0)
3906 return clang_getNullRange();
3907 if (const FunctionDecl *FD =
3908 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
3909 DeclarationNameInfo FunctionName = FD->getNameInfo();
3910 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
3911 }
3912 return clang_getNullRange();
3913 }
3914
Guy Benyei11169dd2012-12-18 14:30:41 +00003915 // FIXME: A CXCursor_InclusionDirective should give the location of the
3916 // filename, but we don't keep track of this.
3917
3918 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3919 // but we don't keep track of this.
3920
3921 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3922 // but we don't keep track of this.
3923
3924 // Default handling, give the location of the cursor.
3925
3926 if (pieceIndex > 0)
3927 return clang_getNullRange();
3928
3929 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3930 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3931 return cxloc::translateSourceRange(Ctx, Loc);
3932}
3933
Eli Bendersky44a206f2014-07-31 18:04:56 +00003934CXString clang_Cursor_getMangling(CXCursor C) {
3935 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
3936 return cxstring::createEmpty();
3937
Eli Bendersky44a206f2014-07-31 18:04:56 +00003938 // Mangling only works for functions and variables.
Eli Bendersky79759592014-08-01 15:01:10 +00003939 const Decl *D = getCursorDecl(C);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003940 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
3941 return cxstring::createEmpty();
3942
Eli Bendersky79759592014-08-01 15:01:10 +00003943 // First apply frontend mangling.
Eli Bendersky44a206f2014-07-31 18:04:56 +00003944 const NamedDecl *ND = cast<NamedDecl>(D);
Eli Bendersky79759592014-08-01 15:01:10 +00003945 ASTContext &Ctx = ND->getASTContext();
3946 std::unique_ptr<MangleContext> MC(Ctx.createMangleContext());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003947
Eli Bendersky79759592014-08-01 15:01:10 +00003948 std::string FrontendBuf;
3949 llvm::raw_string_ostream FrontendBufOS(FrontendBuf);
Ehsan Akhgarif8d44de2015-10-08 00:01:20 +00003950 if (MC->shouldMangleDeclName(ND)) {
3951 MC->mangleName(ND, FrontendBufOS);
3952 } else {
3953 ND->printName(FrontendBufOS);
3954 }
Eli Bendersky44a206f2014-07-31 18:04:56 +00003955
Eli Bendersky79759592014-08-01 15:01:10 +00003956 // Now apply backend mangling.
3957 std::unique_ptr<llvm::DataLayout> DL(
Eric Christopher964a5f32015-08-05 23:48:05 +00003958 new llvm::DataLayout(Ctx.getTargetInfo().getDataLayoutString()));
Eli Bendersky79759592014-08-01 15:01:10 +00003959
3960 std::string FinalBuf;
3961 llvm::raw_string_ostream FinalBufOS(FinalBuf);
Rafael Espindolab633d202015-06-23 13:59:36 +00003962 llvm::Mangler::getNameWithPrefix(FinalBufOS, llvm::Twine(FrontendBufOS.str()),
3963 *DL);
Eli Bendersky79759592014-08-01 15:01:10 +00003964
3965 return cxstring::createDup(FinalBufOS.str());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003966}
3967
Saleem Abdulrasool60034432015-11-12 03:57:22 +00003968CXStringSet *clang_Cursor_getCXXManglings(CXCursor C) {
3969 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
3970 return nullptr;
3971
3972 const Decl *D = getCursorDecl(C);
3973 if (!(isa<CXXRecordDecl>(D) || isa<CXXMethodDecl>(D)))
3974 return nullptr;
3975
3976 const NamedDecl *ND = cast<NamedDecl>(D);
3977
3978 ASTContext &Ctx = ND->getASTContext();
3979 std::unique_ptr<MangleContext> M(Ctx.createMangleContext());
3980 std::unique_ptr<llvm::DataLayout> DL(
3981 new llvm::DataLayout(Ctx.getTargetInfo().getDataLayoutString()));
3982
3983 std::vector<std::string> Manglings;
3984
3985 auto hasDefaultCXXMethodCC = [](ASTContext &C, const CXXMethodDecl *MD) {
3986 auto DefaultCC = C.getDefaultCallingConvention(/*IsVariadic=*/false,
3987 /*IsCSSMethod=*/true);
3988 auto CC = MD->getType()->getAs<FunctionProtoType>()->getCallConv();
3989 return CC == DefaultCC;
3990 };
3991
3992 if (const auto *CD = dyn_cast_or_null<CXXConstructorDecl>(ND)) {
3993 Manglings.emplace_back(getMangledStructor(M, DL, CD, Ctor_Base));
3994
3995 if (Ctx.getTargetInfo().getCXXABI().isItaniumFamily())
3996 if (!CD->getParent()->isAbstract())
3997 Manglings.emplace_back(getMangledStructor(M, DL, CD, Ctor_Complete));
3998
3999 if (Ctx.getTargetInfo().getCXXABI().isMicrosoft())
4000 if (CD->hasAttr<DLLExportAttr>() && CD->isDefaultConstructor())
4001 if (!(hasDefaultCXXMethodCC(Ctx, CD) && CD->getNumParams() == 0))
4002 Manglings.emplace_back(getMangledStructor(M, DL, CD,
4003 Ctor_DefaultClosure));
4004 } else if (const auto *DD = dyn_cast_or_null<CXXDestructorDecl>(ND)) {
4005 Manglings.emplace_back(getMangledStructor(M, DL, DD, Dtor_Base));
4006 if (Ctx.getTargetInfo().getCXXABI().isItaniumFamily()) {
4007 Manglings.emplace_back(getMangledStructor(M, DL, DD, Dtor_Complete));
4008
4009 if (!DD->isVirtual())
4010 Manglings.emplace_back(getMangledStructor(M, DL, DD, Dtor_Deleting));
4011 }
4012 }
4013
4014 return cxstring::createSet(Manglings);
4015}
4016
Guy Benyei11169dd2012-12-18 14:30:41 +00004017CXString clang_getCursorDisplayName(CXCursor C) {
4018 if (!clang_isDeclaration(C.kind))
4019 return clang_getCursorSpelling(C);
4020
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004021 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004022 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004023 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004024
4025 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004026 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004027 D = FunTmpl->getTemplatedDecl();
4028
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004029 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004030 SmallString<64> Str;
4031 llvm::raw_svector_ostream OS(Str);
4032 OS << *Function;
4033 if (Function->getPrimaryTemplate())
4034 OS << "<>";
4035 OS << "(";
4036 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
4037 if (I)
4038 OS << ", ";
4039 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
4040 }
4041
4042 if (Function->isVariadic()) {
4043 if (Function->getNumParams())
4044 OS << ", ";
4045 OS << "...";
4046 }
4047 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004048 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004049 }
4050
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004051 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004052 SmallString<64> Str;
4053 llvm::raw_svector_ostream OS(Str);
4054 OS << *ClassTemplate;
4055 OS << "<";
4056 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
4057 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
4058 if (I)
4059 OS << ", ";
4060
4061 NamedDecl *Param = Params->getParam(I);
4062 if (Param->getIdentifier()) {
4063 OS << Param->getIdentifier()->getName();
4064 continue;
4065 }
4066
4067 // There is no parameter name, which makes this tricky. Try to come up
4068 // with something useful that isn't too long.
4069 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
4070 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
4071 else if (NonTypeTemplateParmDecl *NTTP
4072 = dyn_cast<NonTypeTemplateParmDecl>(Param))
4073 OS << NTTP->getType().getAsString(Policy);
4074 else
4075 OS << "template<...> class";
4076 }
4077
4078 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004079 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004080 }
4081
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004082 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00004083 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
4084 // If the type was explicitly written, use that.
4085 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004086 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00004087
Benjamin Kramer9170e912013-02-22 15:46:01 +00004088 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00004089 llvm::raw_svector_ostream OS(Str);
4090 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00004091 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00004092 ClassSpec->getTemplateArgs().data(),
4093 ClassSpec->getTemplateArgs().size(),
4094 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004095 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004096 }
4097
4098 return clang_getCursorSpelling(C);
4099}
4100
4101CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
4102 switch (Kind) {
4103 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004104 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004105 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004106 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004107 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004108 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004109 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004110 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004111 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004112 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004113 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004114 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004115 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004116 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004117 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004118 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004119 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004120 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004121 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004122 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004123 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004124 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004125 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004126 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004127 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004128 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004129 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004130 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004131 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004132 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004133 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004134 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004135 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004136 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004137 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004138 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004139 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004140 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004141 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004142 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00004143 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004144 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004145 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004146 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004147 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004148 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004149 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004150 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004151 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004152 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004153 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004154 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004155 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004156 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004157 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004158 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004159 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004160 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004161 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004162 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004163 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004164 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004165 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004166 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004167 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004168 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004169 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004170 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004171 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004172 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004173 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004174 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004175 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004176 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004177 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004178 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004179 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004180 return cxstring::createRef("ArraySubscriptExpr");
Alexey Bataev1a3320e2015-08-25 14:24:04 +00004181 case CXCursor_OMPArraySectionExpr:
4182 return cxstring::createRef("OMPArraySectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004183 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004184 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004185 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004186 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004187 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004188 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004189 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004190 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004191 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004192 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004193 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004194 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004195 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004196 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004197 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004198 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004199 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004200 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004201 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004202 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004203 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004204 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004205 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004206 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004207 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004208 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004209 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004210 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004211 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004212 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004213 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004214 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004215 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004216 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004217 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004218 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004219 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004220 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004221 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004222 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004223 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004224 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004225 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004226 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004227 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004228 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004229 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004230 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004231 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004232 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00004233 case CXCursor_ObjCSelfExpr:
4234 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004235 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004236 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004237 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004238 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004239 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004240 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004241 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004242 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004243 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004244 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004245 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004246 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004247 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004248 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004249 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004250 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004251 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004252 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004253 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004254 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004255 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004256 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004257 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004258 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004259 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004260 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004261 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004262 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004263 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004264 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004265 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004266 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004267 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004268 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004269 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004270 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004271 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004272 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004273 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004274 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004275 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004276 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004277 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004278 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004279 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004280 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004281 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004282 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004283 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004284 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004285 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004286 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004287 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004288 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004289 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004290 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004291 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004292 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004293 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004294 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004295 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004296 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004297 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004298 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004299 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004300 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004301 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004302 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004303 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004304 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004305 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004306 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004307 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004308 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004309 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004310 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004311 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004312 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004313 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004314 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004315 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004316 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004317 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004318 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004319 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004320 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004321 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004322 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00004323 case CXCursor_SEHLeaveStmt:
4324 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004325 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004326 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004327 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004328 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00004329 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004330 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00004331 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004332 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00004333 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004334 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00004335 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004336 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00004337 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004338 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004339 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004340 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004341 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004342 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004343 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004344 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004345 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004346 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004347 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004348 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004349 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004350 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004351 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004352 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004353 case CXCursor_PackedAttr:
4354 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00004355 case CXCursor_PureAttr:
4356 return cxstring::createRef("attribute(pure)");
4357 case CXCursor_ConstAttr:
4358 return cxstring::createRef("attribute(const)");
4359 case CXCursor_NoDuplicateAttr:
4360 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00004361 case CXCursor_CUDAConstantAttr:
4362 return cxstring::createRef("attribute(constant)");
4363 case CXCursor_CUDADeviceAttr:
4364 return cxstring::createRef("attribute(device)");
4365 case CXCursor_CUDAGlobalAttr:
4366 return cxstring::createRef("attribute(global)");
4367 case CXCursor_CUDAHostAttr:
4368 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00004369 case CXCursor_CUDASharedAttr:
4370 return cxstring::createRef("attribute(shared)");
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00004371 case CXCursor_VisibilityAttr:
4372 return cxstring::createRef("attribute(visibility)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004373 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004374 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004375 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004376 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00004377 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004378 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004379 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004380 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004381 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004382 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00004383 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004384 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00004385 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004386 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004387 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004388 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004389 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004390 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004391 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004392 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004393 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004394 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004395 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004396 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004397 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004398 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004399 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004400 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004401 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004402 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004403 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004404 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004405 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004406 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004407 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004408 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004409 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004410 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004411 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004412 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004413 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004414 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004415 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004416 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004417 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004418 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004419 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004420 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004421 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004422 return cxstring::createRef("OMPParallelDirective");
4423 case CXCursor_OMPSimdDirective:
4424 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004425 case CXCursor_OMPForDirective:
4426 return cxstring::createRef("OMPForDirective");
Alexander Musmanf82886e2014-09-18 05:12:34 +00004427 case CXCursor_OMPForSimdDirective:
4428 return cxstring::createRef("OMPForSimdDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004429 case CXCursor_OMPSectionsDirective:
4430 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004431 case CXCursor_OMPSectionDirective:
4432 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004433 case CXCursor_OMPSingleDirective:
4434 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004435 case CXCursor_OMPMasterDirective:
4436 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004437 case CXCursor_OMPCriticalDirective:
4438 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004439 case CXCursor_OMPParallelForDirective:
4440 return cxstring::createRef("OMPParallelForDirective");
Alexander Musmane4e893b2014-09-23 09:33:00 +00004441 case CXCursor_OMPParallelForSimdDirective:
4442 return cxstring::createRef("OMPParallelForSimdDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004443 case CXCursor_OMPParallelSectionsDirective:
4444 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004445 case CXCursor_OMPTaskDirective:
4446 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004447 case CXCursor_OMPTaskyieldDirective:
4448 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004449 case CXCursor_OMPBarrierDirective:
4450 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004451 case CXCursor_OMPTaskwaitDirective:
4452 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00004453 case CXCursor_OMPTaskgroupDirective:
4454 return cxstring::createRef("OMPTaskgroupDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00004455 case CXCursor_OMPFlushDirective:
4456 return cxstring::createRef("OMPFlushDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004457 case CXCursor_OMPOrderedDirective:
4458 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00004459 case CXCursor_OMPAtomicDirective:
4460 return cxstring::createRef("OMPAtomicDirective");
Alexey Bataev0bd520b2014-09-19 08:19:49 +00004461 case CXCursor_OMPTargetDirective:
4462 return cxstring::createRef("OMPTargetDirective");
Michael Wong65f367f2015-07-21 13:44:28 +00004463 case CXCursor_OMPTargetDataDirective:
4464 return cxstring::createRef("OMPTargetDataDirective");
Alexey Bataev13314bf2014-10-09 04:18:56 +00004465 case CXCursor_OMPTeamsDirective:
4466 return cxstring::createRef("OMPTeamsDirective");
Alexey Bataev6d4ed052015-07-01 06:57:41 +00004467 case CXCursor_OMPCancellationPointDirective:
4468 return cxstring::createRef("OMPCancellationPointDirective");
Alexey Bataev80909872015-07-02 11:25:17 +00004469 case CXCursor_OMPCancelDirective:
4470 return cxstring::createRef("OMPCancelDirective");
Alexey Bataev49f6e782015-12-01 04:18:41 +00004471 case CXCursor_OMPTaskLoopDirective:
4472 return cxstring::createRef("OMPTaskLoopDirective");
Francisco Lopes da Silva975a9f62015-01-21 16:24:11 +00004473 case CXCursor_OverloadCandidate:
4474 return cxstring::createRef("OverloadCandidate");
Sergey Kalinichev8f3b1872015-11-15 13:48:32 +00004475 case CXCursor_TypeAliasTemplateDecl:
4476 return cxstring::createRef("TypeAliasTemplateDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004477 }
4478
4479 llvm_unreachable("Unhandled CXCursorKind");
4480}
4481
4482struct GetCursorData {
4483 SourceLocation TokenBeginLoc;
4484 bool PointsAtMacroArgExpansion;
4485 bool VisitedObjCPropertyImplDecl;
4486 SourceLocation VisitedDeclaratorDeclStartLoc;
4487 CXCursor &BestCursor;
4488
4489 GetCursorData(SourceManager &SM,
4490 SourceLocation tokenBegin, CXCursor &outputCursor)
4491 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4492 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4493 VisitedObjCPropertyImplDecl = false;
4494 }
4495};
4496
4497static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4498 CXCursor parent,
4499 CXClientData client_data) {
4500 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4501 CXCursor *BestCursor = &Data->BestCursor;
4502
4503 // If we point inside a macro argument we should provide info of what the
4504 // token is so use the actual cursor, don't replace it with a macro expansion
4505 // cursor.
4506 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4507 return CXChildVisit_Recurse;
4508
4509 if (clang_isDeclaration(cursor.kind)) {
4510 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004511 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004512 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4513 if (MD->isImplicit())
4514 return CXChildVisit_Break;
4515
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004516 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004517 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4518 // Check that when we have multiple @class references in the same line,
4519 // that later ones do not override the previous ones.
4520 // If we have:
4521 // @class Foo, Bar;
4522 // source ranges for both start at '@', so 'Bar' will end up overriding
4523 // 'Foo' even though the cursor location was at 'Foo'.
4524 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4525 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004526 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004527 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4528 if (PrevID != ID &&
4529 !PrevID->isThisDeclarationADefinition() &&
4530 !ID->isThisDeclarationADefinition())
4531 return CXChildVisit_Break;
4532 }
4533
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004534 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004535 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4536 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4537 // Check that when we have multiple declarators in the same line,
4538 // that later ones do not override the previous ones.
4539 // If we have:
4540 // int Foo, Bar;
4541 // source ranges for both start at 'int', so 'Bar' will end up overriding
4542 // 'Foo' even though the cursor location was at 'Foo'.
4543 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4544 return CXChildVisit_Break;
4545 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4546
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004547 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004548 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4549 (void)PropImp;
4550 // Check that when we have multiple @synthesize in the same line,
4551 // that later ones do not override the previous ones.
4552 // If we have:
4553 // @synthesize Foo, Bar;
4554 // source ranges for both start at '@', so 'Bar' will end up overriding
4555 // 'Foo' even though the cursor location was at 'Foo'.
4556 if (Data->VisitedObjCPropertyImplDecl)
4557 return CXChildVisit_Break;
4558 Data->VisitedObjCPropertyImplDecl = true;
4559 }
4560 }
4561
4562 if (clang_isExpression(cursor.kind) &&
4563 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004564 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004565 // Avoid having the cursor of an expression replace the declaration cursor
4566 // when the expression source range overlaps the declaration range.
4567 // This can happen for C++ constructor expressions whose range generally
4568 // include the variable declaration, e.g.:
4569 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4570 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4571 D->getLocation() == Data->TokenBeginLoc)
4572 return CXChildVisit_Break;
4573 }
4574 }
4575
4576 // If our current best cursor is the construction of a temporary object,
4577 // don't replace that cursor with a type reference, because we want
4578 // clang_getCursor() to point at the constructor.
4579 if (clang_isExpression(BestCursor->kind) &&
4580 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4581 cursor.kind == CXCursor_TypeRef) {
4582 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4583 // as having the actual point on the type reference.
4584 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4585 return CXChildVisit_Recurse;
4586 }
Douglas Gregore9d95f12015-07-07 03:57:35 +00004587
4588 // If we already have an Objective-C superclass reference, don't
4589 // update it further.
4590 if (BestCursor->kind == CXCursor_ObjCSuperClassRef)
4591 return CXChildVisit_Break;
4592
Guy Benyei11169dd2012-12-18 14:30:41 +00004593 *BestCursor = cursor;
4594 return CXChildVisit_Recurse;
4595}
4596
4597CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004598 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004599 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004600 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004601 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004602
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004603 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004604 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4605
4606 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4607 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4608
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004609 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004610 CXFile SearchFile;
4611 unsigned SearchLine, SearchColumn;
4612 CXFile ResultFile;
4613 unsigned ResultLine, ResultColumn;
4614 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4615 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4616 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004617
4618 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4619 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004620 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004621 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004622 SearchFileName = clang_getFileName(SearchFile);
4623 ResultFileName = clang_getFileName(ResultFile);
4624 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4625 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004626 *Log << llvm::format("(%s:%d:%d) = %s",
4627 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4628 clang_getCString(KindSpelling))
4629 << llvm::format("(%s:%d:%d):%s%s",
4630 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4631 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004632 clang_disposeString(SearchFileName);
4633 clang_disposeString(ResultFileName);
4634 clang_disposeString(KindSpelling);
4635 clang_disposeString(USR);
4636
4637 CXCursor Definition = clang_getCursorDefinition(Result);
4638 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4639 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4640 CXString DefinitionKindSpelling
4641 = clang_getCursorKindSpelling(Definition.kind);
4642 CXFile DefinitionFile;
4643 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004644 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004645 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004646 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004647 *Log << llvm::format(" -> %s(%s:%d:%d)",
4648 clang_getCString(DefinitionKindSpelling),
4649 clang_getCString(DefinitionFileName),
4650 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004651 clang_disposeString(DefinitionFileName);
4652 clang_disposeString(DefinitionKindSpelling);
4653 }
4654 }
4655
4656 return Result;
4657}
4658
4659CXCursor clang_getNullCursor(void) {
4660 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4661}
4662
4663unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004664 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4665 // can't set consistently. For example, when visiting a DeclStmt we will set
4666 // it but we don't set it on the result of clang_getCursorDefinition for
4667 // a reference of the same declaration.
4668 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4669 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4670 // to provide that kind of info.
4671 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004672 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004673 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004674 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004675
Guy Benyei11169dd2012-12-18 14:30:41 +00004676 return X == Y;
4677}
4678
4679unsigned clang_hashCursor(CXCursor C) {
4680 unsigned Index = 0;
4681 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4682 Index = 1;
4683
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004684 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004685 std::make_pair(C.kind, C.data[Index]));
4686}
4687
4688unsigned clang_isInvalid(enum CXCursorKind K) {
4689 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4690}
4691
4692unsigned clang_isDeclaration(enum CXCursorKind K) {
4693 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4694 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4695}
4696
4697unsigned clang_isReference(enum CXCursorKind K) {
4698 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4699}
4700
4701unsigned clang_isExpression(enum CXCursorKind K) {
4702 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4703}
4704
4705unsigned clang_isStatement(enum CXCursorKind K) {
4706 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4707}
4708
4709unsigned clang_isAttribute(enum CXCursorKind K) {
4710 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4711}
4712
4713unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4714 return K == CXCursor_TranslationUnit;
4715}
4716
4717unsigned clang_isPreprocessing(enum CXCursorKind K) {
4718 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4719}
4720
4721unsigned clang_isUnexposed(enum CXCursorKind K) {
4722 switch (K) {
4723 case CXCursor_UnexposedDecl:
4724 case CXCursor_UnexposedExpr:
4725 case CXCursor_UnexposedStmt:
4726 case CXCursor_UnexposedAttr:
4727 return true;
4728 default:
4729 return false;
4730 }
4731}
4732
4733CXCursorKind clang_getCursorKind(CXCursor C) {
4734 return C.kind;
4735}
4736
4737CXSourceLocation clang_getCursorLocation(CXCursor C) {
4738 if (clang_isReference(C.kind)) {
4739 switch (C.kind) {
4740 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004741 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004742 = getCursorObjCSuperClassRef(C);
4743 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4744 }
4745
4746 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004747 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004748 = getCursorObjCProtocolRef(C);
4749 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4750 }
4751
4752 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004753 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004754 = getCursorObjCClassRef(C);
4755 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4756 }
4757
4758 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004759 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004760 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4761 }
4762
4763 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004764 std::pair<const TemplateDecl *, SourceLocation> P =
4765 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004766 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4767 }
4768
4769 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004770 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004771 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4772 }
4773
4774 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004775 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004776 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4777 }
4778
4779 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004780 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004781 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4782 }
4783
4784 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004785 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004786 if (!BaseSpec)
4787 return clang_getNullLocation();
4788
4789 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4790 return cxloc::translateSourceLocation(getCursorContext(C),
4791 TSInfo->getTypeLoc().getBeginLoc());
4792
4793 return cxloc::translateSourceLocation(getCursorContext(C),
4794 BaseSpec->getLocStart());
4795 }
4796
4797 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004798 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004799 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4800 }
4801
4802 case CXCursor_OverloadedDeclRef:
4803 return cxloc::translateSourceLocation(getCursorContext(C),
4804 getCursorOverloadedDeclRef(C).second);
4805
4806 default:
4807 // FIXME: Need a way to enumerate all non-reference cases.
4808 llvm_unreachable("Missed a reference kind");
4809 }
4810 }
4811
4812 if (clang_isExpression(C.kind))
4813 return cxloc::translateSourceLocation(getCursorContext(C),
4814 getLocationFromExpr(getCursorExpr(C)));
4815
4816 if (clang_isStatement(C.kind))
4817 return cxloc::translateSourceLocation(getCursorContext(C),
4818 getCursorStmt(C)->getLocStart());
4819
4820 if (C.kind == CXCursor_PreprocessingDirective) {
4821 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4822 return cxloc::translateSourceLocation(getCursorContext(C), L);
4823 }
4824
4825 if (C.kind == CXCursor_MacroExpansion) {
4826 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004827 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004828 return cxloc::translateSourceLocation(getCursorContext(C), L);
4829 }
4830
4831 if (C.kind == CXCursor_MacroDefinition) {
4832 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4833 return cxloc::translateSourceLocation(getCursorContext(C), L);
4834 }
4835
4836 if (C.kind == CXCursor_InclusionDirective) {
4837 SourceLocation L
4838 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4839 return cxloc::translateSourceLocation(getCursorContext(C), L);
4840 }
4841
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004842 if (clang_isAttribute(C.kind)) {
4843 SourceLocation L
4844 = cxcursor::getCursorAttr(C)->getLocation();
4845 return cxloc::translateSourceLocation(getCursorContext(C), L);
4846 }
4847
Guy Benyei11169dd2012-12-18 14:30:41 +00004848 if (!clang_isDeclaration(C.kind))
4849 return clang_getNullLocation();
4850
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004851 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004852 if (!D)
4853 return clang_getNullLocation();
4854
4855 SourceLocation Loc = D->getLocation();
4856 // FIXME: Multiple variables declared in a single declaration
4857 // currently lack the information needed to correctly determine their
4858 // ranges when accounting for the type-specifier. We use context
4859 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4860 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004861 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004862 if (!cxcursor::isFirstInDeclGroup(C))
4863 Loc = VD->getLocation();
4864 }
4865
4866 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004867 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004868 Loc = MD->getSelectorStartLoc();
4869
4870 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4871}
4872
4873} // end extern "C"
4874
4875CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4876 assert(TU);
4877
4878 // Guard against an invalid SourceLocation, or we may assert in one
4879 // of the following calls.
4880 if (SLoc.isInvalid())
4881 return clang_getNullCursor();
4882
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004883 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004884
4885 // Translate the given source location to make it point at the beginning of
4886 // the token under the cursor.
4887 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4888 CXXUnit->getASTContext().getLangOpts());
4889
4890 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4891 if (SLoc.isValid()) {
4892 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4893 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4894 /*VisitPreprocessorLast=*/true,
4895 /*VisitIncludedEntities=*/false,
4896 SourceLocation(SLoc));
4897 CursorVis.visitFileRegion();
4898 }
4899
4900 return Result;
4901}
4902
4903static SourceRange getRawCursorExtent(CXCursor C) {
4904 if (clang_isReference(C.kind)) {
4905 switch (C.kind) {
4906 case CXCursor_ObjCSuperClassRef:
4907 return getCursorObjCSuperClassRef(C).second;
4908
4909 case CXCursor_ObjCProtocolRef:
4910 return getCursorObjCProtocolRef(C).second;
4911
4912 case CXCursor_ObjCClassRef:
4913 return getCursorObjCClassRef(C).second;
4914
4915 case CXCursor_TypeRef:
4916 return getCursorTypeRef(C).second;
4917
4918 case CXCursor_TemplateRef:
4919 return getCursorTemplateRef(C).second;
4920
4921 case CXCursor_NamespaceRef:
4922 return getCursorNamespaceRef(C).second;
4923
4924 case CXCursor_MemberRef:
4925 return getCursorMemberRef(C).second;
4926
4927 case CXCursor_CXXBaseSpecifier:
4928 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4929
4930 case CXCursor_LabelRef:
4931 return getCursorLabelRef(C).second;
4932
4933 case CXCursor_OverloadedDeclRef:
4934 return getCursorOverloadedDeclRef(C).second;
4935
4936 case CXCursor_VariableRef:
4937 return getCursorVariableRef(C).second;
4938
4939 default:
4940 // FIXME: Need a way to enumerate all non-reference cases.
4941 llvm_unreachable("Missed a reference kind");
4942 }
4943 }
4944
4945 if (clang_isExpression(C.kind))
4946 return getCursorExpr(C)->getSourceRange();
4947
4948 if (clang_isStatement(C.kind))
4949 return getCursorStmt(C)->getSourceRange();
4950
4951 if (clang_isAttribute(C.kind))
4952 return getCursorAttr(C)->getRange();
4953
4954 if (C.kind == CXCursor_PreprocessingDirective)
4955 return cxcursor::getCursorPreprocessingDirective(C);
4956
4957 if (C.kind == CXCursor_MacroExpansion) {
4958 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004959 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004960 return TU->mapRangeFromPreamble(Range);
4961 }
4962
4963 if (C.kind == CXCursor_MacroDefinition) {
4964 ASTUnit *TU = getCursorASTUnit(C);
4965 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4966 return TU->mapRangeFromPreamble(Range);
4967 }
4968
4969 if (C.kind == CXCursor_InclusionDirective) {
4970 ASTUnit *TU = getCursorASTUnit(C);
4971 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4972 return TU->mapRangeFromPreamble(Range);
4973 }
4974
4975 if (C.kind == CXCursor_TranslationUnit) {
4976 ASTUnit *TU = getCursorASTUnit(C);
4977 FileID MainID = TU->getSourceManager().getMainFileID();
4978 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4979 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4980 return SourceRange(Start, End);
4981 }
4982
4983 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004984 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004985 if (!D)
4986 return SourceRange();
4987
4988 SourceRange R = D->getSourceRange();
4989 // FIXME: Multiple variables declared in a single declaration
4990 // currently lack the information needed to correctly determine their
4991 // ranges when accounting for the type-specifier. We use context
4992 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4993 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004994 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004995 if (!cxcursor::isFirstInDeclGroup(C))
4996 R.setBegin(VD->getLocation());
4997 }
4998 return R;
4999 }
5000 return SourceRange();
5001}
5002
5003/// \brief Retrieves the "raw" cursor extent, which is then extended to include
5004/// the decl-specifier-seq for declarations.
5005static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
5006 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005007 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005008 if (!D)
5009 return SourceRange();
5010
5011 SourceRange R = D->getSourceRange();
5012
5013 // Adjust the start of the location for declarations preceded by
5014 // declaration specifiers.
5015 SourceLocation StartLoc;
5016 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
5017 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
5018 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005019 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005020 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
5021 StartLoc = TI->getTypeLoc().getLocStart();
5022 }
5023
5024 if (StartLoc.isValid() && R.getBegin().isValid() &&
5025 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
5026 R.setBegin(StartLoc);
5027
5028 // FIXME: Multiple variables declared in a single declaration
5029 // currently lack the information needed to correctly determine their
5030 // ranges when accounting for the type-specifier. We use context
5031 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
5032 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005033 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005034 if (!cxcursor::isFirstInDeclGroup(C))
5035 R.setBegin(VD->getLocation());
5036 }
5037
5038 return R;
5039 }
5040
5041 return getRawCursorExtent(C);
5042}
5043
5044extern "C" {
5045
5046CXSourceRange clang_getCursorExtent(CXCursor C) {
5047 SourceRange R = getRawCursorExtent(C);
5048 if (R.isInvalid())
5049 return clang_getNullRange();
5050
5051 return cxloc::translateSourceRange(getCursorContext(C), R);
5052}
5053
5054CXCursor clang_getCursorReferenced(CXCursor C) {
5055 if (clang_isInvalid(C.kind))
5056 return clang_getNullCursor();
5057
5058 CXTranslationUnit tu = getCursorTU(C);
5059 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005060 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005061 if (!D)
5062 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005063 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005064 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005065 if (const ObjCPropertyImplDecl *PropImpl =
5066 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005067 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
5068 return MakeCXCursor(Property, tu);
5069
5070 return C;
5071 }
5072
5073 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005074 const Expr *E = getCursorExpr(C);
5075 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00005076 if (D) {
5077 CXCursor declCursor = MakeCXCursor(D, tu);
5078 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
5079 declCursor);
5080 return declCursor;
5081 }
5082
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005083 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00005084 return MakeCursorOverloadedDeclRef(Ovl, tu);
5085
5086 return clang_getNullCursor();
5087 }
5088
5089 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005090 const Stmt *S = getCursorStmt(C);
5091 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00005092 if (LabelDecl *label = Goto->getLabel())
5093 if (LabelStmt *labelS = label->getStmt())
5094 return MakeCXCursor(labelS, getCursorDecl(C), tu);
5095
5096 return clang_getNullCursor();
5097 }
Richard Smith66a81862015-05-04 02:25:31 +00005098
Guy Benyei11169dd2012-12-18 14:30:41 +00005099 if (C.kind == CXCursor_MacroExpansion) {
Richard Smith66a81862015-05-04 02:25:31 +00005100 if (const MacroDefinitionRecord *Def =
5101 getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005102 return MakeMacroDefinitionCursor(Def, tu);
5103 }
5104
5105 if (!clang_isReference(C.kind))
5106 return clang_getNullCursor();
5107
5108 switch (C.kind) {
5109 case CXCursor_ObjCSuperClassRef:
5110 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
5111
5112 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005113 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
5114 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005115 return MakeCXCursor(Def, tu);
5116
5117 return MakeCXCursor(Prot, tu);
5118 }
5119
5120 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005121 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
5122 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005123 return MakeCXCursor(Def, tu);
5124
5125 return MakeCXCursor(Class, tu);
5126 }
5127
5128 case CXCursor_TypeRef:
5129 return MakeCXCursor(getCursorTypeRef(C).first, tu );
5130
5131 case CXCursor_TemplateRef:
5132 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
5133
5134 case CXCursor_NamespaceRef:
5135 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
5136
5137 case CXCursor_MemberRef:
5138 return MakeCXCursor(getCursorMemberRef(C).first, tu );
5139
5140 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005141 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005142 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
5143 tu ));
5144 }
5145
5146 case CXCursor_LabelRef:
5147 // FIXME: We end up faking the "parent" declaration here because we
5148 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005149 return MakeCXCursor(getCursorLabelRef(C).first,
5150 cxtu::getASTUnit(tu)->getASTContext()
5151 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00005152 tu);
5153
5154 case CXCursor_OverloadedDeclRef:
5155 return C;
5156
5157 case CXCursor_VariableRef:
5158 return MakeCXCursor(getCursorVariableRef(C).first, tu);
5159
5160 default:
5161 // We would prefer to enumerate all non-reference cursor kinds here.
5162 llvm_unreachable("Unhandled reference cursor kind");
5163 }
5164}
5165
5166CXCursor clang_getCursorDefinition(CXCursor C) {
5167 if (clang_isInvalid(C.kind))
5168 return clang_getNullCursor();
5169
5170 CXTranslationUnit TU = getCursorTU(C);
5171
5172 bool WasReference = false;
5173 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
5174 C = clang_getCursorReferenced(C);
5175 WasReference = true;
5176 }
5177
5178 if (C.kind == CXCursor_MacroExpansion)
5179 return clang_getCursorReferenced(C);
5180
5181 if (!clang_isDeclaration(C.kind))
5182 return clang_getNullCursor();
5183
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005184 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005185 if (!D)
5186 return clang_getNullCursor();
5187
5188 switch (D->getKind()) {
5189 // Declaration kinds that don't really separate the notions of
5190 // declaration and definition.
5191 case Decl::Namespace:
5192 case Decl::Typedef:
5193 case Decl::TypeAlias:
5194 case Decl::TypeAliasTemplate:
5195 case Decl::TemplateTypeParm:
5196 case Decl::EnumConstant:
5197 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00005198 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005199 case Decl::IndirectField:
5200 case Decl::ObjCIvar:
5201 case Decl::ObjCAtDefsField:
5202 case Decl::ImplicitParam:
5203 case Decl::ParmVar:
5204 case Decl::NonTypeTemplateParm:
5205 case Decl::TemplateTemplateParm:
5206 case Decl::ObjCCategoryImpl:
5207 case Decl::ObjCImplementation:
5208 case Decl::AccessSpec:
5209 case Decl::LinkageSpec:
5210 case Decl::ObjCPropertyImpl:
5211 case Decl::FileScopeAsm:
5212 case Decl::StaticAssert:
5213 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00005214 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00005215 case Decl::Label: // FIXME: Is this right??
5216 case Decl::ClassScopeFunctionSpecialization:
5217 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00005218 case Decl::OMPThreadPrivate:
Douglas Gregor85f3f952015-07-07 03:57:15 +00005219 case Decl::ObjCTypeParam:
David Majnemerd9b1a4f2015-11-04 03:40:30 +00005220 case Decl::BuiltinTemplate:
Guy Benyei11169dd2012-12-18 14:30:41 +00005221 return C;
5222
5223 // Declaration kinds that don't make any sense here, but are
5224 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00005225 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005226 case Decl::TranslationUnit:
Richard Smithf19e1272015-03-07 00:04:49 +00005227 case Decl::ExternCContext:
Guy Benyei11169dd2012-12-18 14:30:41 +00005228 break;
5229
5230 // Declaration kinds for which the definition is not resolvable.
5231 case Decl::UnresolvedUsingTypename:
5232 case Decl::UnresolvedUsingValue:
5233 break;
5234
5235 case Decl::UsingDirective:
5236 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
5237 TU);
5238
5239 case Decl::NamespaceAlias:
5240 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
5241
5242 case Decl::Enum:
5243 case Decl::Record:
5244 case Decl::CXXRecord:
5245 case Decl::ClassTemplateSpecialization:
5246 case Decl::ClassTemplatePartialSpecialization:
5247 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
5248 return MakeCXCursor(Def, TU);
5249 return clang_getNullCursor();
5250
5251 case Decl::Function:
5252 case Decl::CXXMethod:
5253 case Decl::CXXConstructor:
5254 case Decl::CXXDestructor:
5255 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00005256 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005257 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00005258 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005259 return clang_getNullCursor();
5260 }
5261
Larisse Voufo39a1e502013-08-06 01:03:05 +00005262 case Decl::Var:
5263 case Decl::VarTemplateSpecialization:
5264 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00005265 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005266 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005267 return MakeCXCursor(Def, TU);
5268 return clang_getNullCursor();
5269 }
5270
5271 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00005272 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005273 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
5274 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
5275 return clang_getNullCursor();
5276 }
5277
5278 case Decl::ClassTemplate: {
5279 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
5280 ->getDefinition())
5281 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
5282 TU);
5283 return clang_getNullCursor();
5284 }
5285
Larisse Voufo39a1e502013-08-06 01:03:05 +00005286 case Decl::VarTemplate: {
5287 if (VarDecl *Def =
5288 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
5289 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
5290 return clang_getNullCursor();
5291 }
5292
Guy Benyei11169dd2012-12-18 14:30:41 +00005293 case Decl::Using:
5294 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
5295 D->getLocation(), TU);
5296
5297 case Decl::UsingShadow:
5298 return clang_getCursorDefinition(
5299 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
5300 TU));
5301
5302 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005303 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005304 if (Method->isThisDeclarationADefinition())
5305 return C;
5306
5307 // Dig out the method definition in the associated
5308 // @implementation, if we have it.
5309 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005310 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005311 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
5312 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
5313 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
5314 Method->isInstanceMethod()))
5315 if (Def->isThisDeclarationADefinition())
5316 return MakeCXCursor(Def, TU);
5317
5318 return clang_getNullCursor();
5319 }
5320
5321 case Decl::ObjCCategory:
5322 if (ObjCCategoryImplDecl *Impl
5323 = cast<ObjCCategoryDecl>(D)->getImplementation())
5324 return MakeCXCursor(Impl, TU);
5325 return clang_getNullCursor();
5326
5327 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005328 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005329 return MakeCXCursor(Def, TU);
5330 return clang_getNullCursor();
5331
5332 case Decl::ObjCInterface: {
5333 // There are two notions of a "definition" for an Objective-C
5334 // class: the interface and its implementation. When we resolved a
5335 // reference to an Objective-C class, produce the @interface as
5336 // the definition; when we were provided with the interface,
5337 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005338 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005339 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005340 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005341 return MakeCXCursor(Def, TU);
5342 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
5343 return MakeCXCursor(Impl, TU);
5344 return clang_getNullCursor();
5345 }
5346
5347 case Decl::ObjCProperty:
5348 // FIXME: We don't really know where to find the
5349 // ObjCPropertyImplDecls that implement this property.
5350 return clang_getNullCursor();
5351
5352 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005353 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005354 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005355 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005356 return MakeCXCursor(Def, TU);
5357
5358 return clang_getNullCursor();
5359
5360 case Decl::Friend:
5361 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
5362 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5363 return clang_getNullCursor();
5364
5365 case Decl::FriendTemplate:
5366 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
5367 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5368 return clang_getNullCursor();
5369 }
5370
5371 return clang_getNullCursor();
5372}
5373
5374unsigned clang_isCursorDefinition(CXCursor C) {
5375 if (!clang_isDeclaration(C.kind))
5376 return 0;
5377
5378 return clang_getCursorDefinition(C) == C;
5379}
5380
5381CXCursor clang_getCanonicalCursor(CXCursor C) {
5382 if (!clang_isDeclaration(C.kind))
5383 return C;
5384
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005385 if (const Decl *D = getCursorDecl(C)) {
5386 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005387 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5388 return MakeCXCursor(CatD, getCursorTU(C));
5389
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005390 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5391 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00005392 return MakeCXCursor(IFD, getCursorTU(C));
5393
5394 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5395 }
5396
5397 return C;
5398}
5399
5400int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5401 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5402}
5403
5404unsigned clang_getNumOverloadedDecls(CXCursor C) {
5405 if (C.kind != CXCursor_OverloadedDeclRef)
5406 return 0;
5407
5408 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005409 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005410 return E->getNumDecls();
5411
5412 if (OverloadedTemplateStorage *S
5413 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5414 return S->size();
5415
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005416 const Decl *D = Storage.get<const Decl *>();
5417 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005418 return Using->shadow_size();
5419
5420 return 0;
5421}
5422
5423CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5424 if (cursor.kind != CXCursor_OverloadedDeclRef)
5425 return clang_getNullCursor();
5426
5427 if (index >= clang_getNumOverloadedDecls(cursor))
5428 return clang_getNullCursor();
5429
5430 CXTranslationUnit TU = getCursorTU(cursor);
5431 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005432 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005433 return MakeCXCursor(E->decls_begin()[index], TU);
5434
5435 if (OverloadedTemplateStorage *S
5436 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5437 return MakeCXCursor(S->begin()[index], TU);
5438
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005439 const Decl *D = Storage.get<const Decl *>();
5440 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005441 // FIXME: This is, unfortunately, linear time.
5442 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5443 std::advance(Pos, index);
5444 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5445 }
5446
5447 return clang_getNullCursor();
5448}
5449
5450void clang_getDefinitionSpellingAndExtent(CXCursor C,
5451 const char **startBuf,
5452 const char **endBuf,
5453 unsigned *startLine,
5454 unsigned *startColumn,
5455 unsigned *endLine,
5456 unsigned *endColumn) {
5457 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005458 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005459 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5460
5461 SourceManager &SM = FD->getASTContext().getSourceManager();
5462 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5463 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5464 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5465 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5466 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5467 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5468}
5469
5470
5471CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5472 unsigned PieceIndex) {
5473 RefNamePieces Pieces;
5474
5475 switch (C.kind) {
5476 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005477 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005478 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5479 E->getQualifierLoc().getSourceRange());
5480 break;
5481
5482 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005483 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005484 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
5485 E->getQualifierLoc().getSourceRange(),
5486 E->getOptionalExplicitTemplateArgs());
5487 break;
5488
5489 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005490 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005491 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005492 const Expr *Callee = OCE->getCallee();
5493 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005494 Callee = ICE->getSubExpr();
5495
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005496 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005497 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5498 DRE->getQualifierLoc().getSourceRange());
5499 }
5500 break;
5501
5502 default:
5503 break;
5504 }
5505
5506 if (Pieces.empty()) {
5507 if (PieceIndex == 0)
5508 return clang_getCursorExtent(C);
5509 } else if (PieceIndex < Pieces.size()) {
5510 SourceRange R = Pieces[PieceIndex];
5511 if (R.isValid())
5512 return cxloc::translateSourceRange(getCursorContext(C), R);
5513 }
5514
5515 return clang_getNullRange();
5516}
5517
5518void clang_enableStackTraces(void) {
5519 llvm::sys::PrintStackTraceOnErrorSignal();
5520}
5521
5522void clang_executeOnThread(void (*fn)(void*), void *user_data,
5523 unsigned stack_size) {
5524 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5525}
5526
5527} // end: extern "C"
5528
5529//===----------------------------------------------------------------------===//
5530// Token-based Operations.
5531//===----------------------------------------------------------------------===//
5532
5533/* CXToken layout:
5534 * int_data[0]: a CXTokenKind
5535 * int_data[1]: starting token location
5536 * int_data[2]: token length
5537 * int_data[3]: reserved
5538 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5539 * otherwise unused.
5540 */
5541extern "C" {
5542
5543CXTokenKind clang_getTokenKind(CXToken CXTok) {
5544 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5545}
5546
5547CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5548 switch (clang_getTokenKind(CXTok)) {
5549 case CXToken_Identifier:
5550 case CXToken_Keyword:
5551 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005552 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005553 ->getNameStart());
5554
5555 case CXToken_Literal: {
5556 // We have stashed the starting pointer in the ptr_data field. Use it.
5557 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005558 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005559 }
5560
5561 case CXToken_Punctuation:
5562 case CXToken_Comment:
5563 break;
5564 }
5565
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005566 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005567 LOG_BAD_TU(TU);
5568 return cxstring::createEmpty();
5569 }
5570
Guy Benyei11169dd2012-12-18 14:30:41 +00005571 // We have to find the starting buffer pointer the hard way, by
5572 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005573 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005574 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005575 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005576
5577 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5578 std::pair<FileID, unsigned> LocInfo
5579 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5580 bool Invalid = false;
5581 StringRef Buffer
5582 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5583 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005584 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005585
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005586 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005587}
5588
5589CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005590 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005591 LOG_BAD_TU(TU);
5592 return clang_getNullLocation();
5593 }
5594
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005595 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005596 if (!CXXUnit)
5597 return clang_getNullLocation();
5598
5599 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5600 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5601}
5602
5603CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005604 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005605 LOG_BAD_TU(TU);
5606 return clang_getNullRange();
5607 }
5608
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005609 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005610 if (!CXXUnit)
5611 return clang_getNullRange();
5612
5613 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5614 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5615}
5616
5617static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5618 SmallVectorImpl<CXToken> &CXTokens) {
5619 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5620 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005621 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005622 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005623 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005624
5625 // Cannot tokenize across files.
5626 if (BeginLocInfo.first != EndLocInfo.first)
5627 return;
5628
5629 // Create a lexer
5630 bool Invalid = false;
5631 StringRef Buffer
5632 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5633 if (Invalid)
5634 return;
5635
5636 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5637 CXXUnit->getASTContext().getLangOpts(),
5638 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5639 Lex.SetCommentRetentionState(true);
5640
5641 // Lex tokens until we hit the end of the range.
5642 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5643 Token Tok;
5644 bool previousWasAt = false;
5645 do {
5646 // Lex the next token
5647 Lex.LexFromRawLexer(Tok);
5648 if (Tok.is(tok::eof))
5649 break;
5650
5651 // Initialize the CXToken.
5652 CXToken CXTok;
5653
5654 // - Common fields
5655 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5656 CXTok.int_data[2] = Tok.getLength();
5657 CXTok.int_data[3] = 0;
5658
5659 // - Kind-specific fields
5660 if (Tok.isLiteral()) {
5661 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005662 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005663 } else if (Tok.is(tok::raw_identifier)) {
5664 // Lookup the identifier to determine whether we have a keyword.
5665 IdentifierInfo *II
5666 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5667
5668 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5669 CXTok.int_data[0] = CXToken_Keyword;
5670 }
5671 else {
5672 CXTok.int_data[0] = Tok.is(tok::identifier)
5673 ? CXToken_Identifier
5674 : CXToken_Keyword;
5675 }
5676 CXTok.ptr_data = II;
5677 } else if (Tok.is(tok::comment)) {
5678 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005679 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005680 } else {
5681 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005682 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005683 }
5684 CXTokens.push_back(CXTok);
5685 previousWasAt = Tok.is(tok::at);
5686 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5687}
5688
5689void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5690 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005691 LOG_FUNC_SECTION {
5692 *Log << TU << ' ' << Range;
5693 }
5694
Guy Benyei11169dd2012-12-18 14:30:41 +00005695 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005696 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005697 if (NumTokens)
5698 *NumTokens = 0;
5699
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005700 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005701 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005702 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005703 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005704
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005705 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005706 if (!CXXUnit || !Tokens || !NumTokens)
5707 return;
5708
5709 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5710
5711 SourceRange R = cxloc::translateCXSourceRange(Range);
5712 if (R.isInvalid())
5713 return;
5714
5715 SmallVector<CXToken, 32> CXTokens;
5716 getTokens(CXXUnit, R, CXTokens);
5717
5718 if (CXTokens.empty())
5719 return;
5720
5721 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5722 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5723 *NumTokens = CXTokens.size();
5724}
5725
5726void clang_disposeTokens(CXTranslationUnit TU,
5727 CXToken *Tokens, unsigned NumTokens) {
5728 free(Tokens);
5729}
5730
5731} // end: extern "C"
5732
5733//===----------------------------------------------------------------------===//
5734// Token annotation APIs.
5735//===----------------------------------------------------------------------===//
5736
Guy Benyei11169dd2012-12-18 14:30:41 +00005737static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5738 CXCursor parent,
5739 CXClientData client_data);
5740static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5741 CXClientData client_data);
5742
5743namespace {
5744class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005745 CXToken *Tokens;
5746 CXCursor *Cursors;
5747 unsigned NumTokens;
5748 unsigned TokIdx;
5749 unsigned PreprocessingTokIdx;
5750 CursorVisitor AnnotateVis;
5751 SourceManager &SrcMgr;
5752 bool HasContextSensitiveKeywords;
5753
5754 struct PostChildrenInfo {
5755 CXCursor Cursor;
5756 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005757 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005758 unsigned BeforeChildrenTokenIdx;
5759 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005760 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005761
5762 CXToken &getTok(unsigned Idx) {
5763 assert(Idx < NumTokens);
5764 return Tokens[Idx];
5765 }
5766 const CXToken &getTok(unsigned Idx) const {
5767 assert(Idx < NumTokens);
5768 return Tokens[Idx];
5769 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005770 bool MoreTokens() const { return TokIdx < NumTokens; }
5771 unsigned NextToken() const { return TokIdx; }
5772 void AdvanceToken() { ++TokIdx; }
5773 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005774 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005775 }
5776 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005777 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005778 }
5779 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005780 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005781 }
5782
5783 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005784 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005785 SourceRange);
5786
5787public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005788 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005789 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005790 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005791 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005792 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005793 AnnotateTokensVisitor, this,
5794 /*VisitPreprocessorLast=*/true,
5795 /*VisitIncludedEntities=*/false,
5796 RegionOfInterest,
5797 /*VisitDeclsOnly=*/false,
5798 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005799 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005800 HasContextSensitiveKeywords(false) { }
5801
5802 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5803 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5804 bool postVisitChildren(CXCursor cursor);
5805 void AnnotateTokens();
5806
5807 /// \brief Determine whether the annotator saw any cursors that have
5808 /// context-sensitive keywords.
5809 bool hasContextSensitiveKeywords() const {
5810 return HasContextSensitiveKeywords;
5811 }
5812
5813 ~AnnotateTokensWorker() {
5814 assert(PostChildrenInfos.empty());
5815 }
5816};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00005817}
Guy Benyei11169dd2012-12-18 14:30:41 +00005818
5819void AnnotateTokensWorker::AnnotateTokens() {
5820 // Walk the AST within the region of interest, annotating tokens
5821 // along the way.
5822 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005823}
Guy Benyei11169dd2012-12-18 14:30:41 +00005824
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005825static inline void updateCursorAnnotation(CXCursor &Cursor,
5826 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005827 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005828 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005829 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005830}
5831
5832/// \brief It annotates and advances tokens with a cursor until the comparison
5833//// between the cursor location and the source range is the same as
5834/// \arg compResult.
5835///
5836/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5837/// Pass RangeOverlap to annotate tokens inside a range.
5838void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5839 RangeComparisonResult compResult,
5840 SourceRange range) {
5841 while (MoreTokens()) {
5842 const unsigned I = NextToken();
5843 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005844 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5845 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005846
5847 SourceLocation TokLoc = GetTokenLoc(I);
5848 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005849 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005850 AdvanceToken();
5851 continue;
5852 }
5853 break;
5854 }
5855}
5856
5857/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005858/// \returns true if it advanced beyond all macro tokens, false otherwise.
5859bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005860 CXCursor updateC,
5861 RangeComparisonResult compResult,
5862 SourceRange range) {
5863 assert(MoreTokens());
5864 assert(isFunctionMacroToken(NextToken()) &&
5865 "Should be called only for macro arg tokens");
5866
5867 // This works differently than annotateAndAdvanceTokens; because expanded
5868 // macro arguments can have arbitrary translation-unit source order, we do not
5869 // advance the token index one by one until a token fails the range test.
5870 // We only advance once past all of the macro arg tokens if all of them
5871 // pass the range test. If one of them fails we keep the token index pointing
5872 // at the start of the macro arg tokens so that the failing token will be
5873 // annotated by a subsequent annotation try.
5874
5875 bool atLeastOneCompFail = false;
5876
5877 unsigned I = NextToken();
5878 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5879 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5880 if (TokLoc.isFileID())
5881 continue; // not macro arg token, it's parens or comma.
5882 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5883 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5884 Cursors[I] = updateC;
5885 } else
5886 atLeastOneCompFail = true;
5887 }
5888
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005889 if (atLeastOneCompFail)
5890 return false;
5891
5892 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5893 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005894}
5895
5896enum CXChildVisitResult
5897AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005898 SourceRange cursorRange = getRawCursorExtent(cursor);
5899 if (cursorRange.isInvalid())
5900 return CXChildVisit_Recurse;
5901
5902 if (!HasContextSensitiveKeywords) {
5903 // Objective-C properties can have context-sensitive keywords.
5904 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005905 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005906 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5907 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5908 }
5909 // Objective-C methods can have context-sensitive keywords.
5910 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5911 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005912 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005913 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5914 if (Method->getObjCDeclQualifier())
5915 HasContextSensitiveKeywords = true;
5916 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005917 for (const auto *P : Method->params()) {
5918 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005919 HasContextSensitiveKeywords = true;
5920 break;
5921 }
5922 }
5923 }
5924 }
5925 }
5926 // C++ methods can have context-sensitive keywords.
5927 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005928 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005929 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5930 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5931 HasContextSensitiveKeywords = true;
5932 }
5933 }
5934 // C++ classes can have context-sensitive keywords.
5935 else if (cursor.kind == CXCursor_StructDecl ||
5936 cursor.kind == CXCursor_ClassDecl ||
5937 cursor.kind == CXCursor_ClassTemplate ||
5938 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005939 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005940 if (D->hasAttr<FinalAttr>())
5941 HasContextSensitiveKeywords = true;
5942 }
5943 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005944
5945 // Don't override a property annotation with its getter/setter method.
5946 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5947 parent.kind == CXCursor_ObjCPropertyDecl)
5948 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005949
5950 if (clang_isPreprocessing(cursor.kind)) {
5951 // Items in the preprocessing record are kept separate from items in
5952 // declarations, so we keep a separate token index.
5953 unsigned SavedTokIdx = TokIdx;
5954 TokIdx = PreprocessingTokIdx;
5955
5956 // Skip tokens up until we catch up to the beginning of the preprocessing
5957 // entry.
5958 while (MoreTokens()) {
5959 const unsigned I = NextToken();
5960 SourceLocation TokLoc = GetTokenLoc(I);
5961 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5962 case RangeBefore:
5963 AdvanceToken();
5964 continue;
5965 case RangeAfter:
5966 case RangeOverlap:
5967 break;
5968 }
5969 break;
5970 }
5971
5972 // Look at all of the tokens within this range.
5973 while (MoreTokens()) {
5974 const unsigned I = NextToken();
5975 SourceLocation TokLoc = GetTokenLoc(I);
5976 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5977 case RangeBefore:
5978 llvm_unreachable("Infeasible");
5979 case RangeAfter:
5980 break;
5981 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005982 // For macro expansions, just note where the beginning of the macro
5983 // expansion occurs.
5984 if (cursor.kind == CXCursor_MacroExpansion) {
5985 if (TokLoc == cursorRange.getBegin())
5986 Cursors[I] = cursor;
5987 AdvanceToken();
5988 break;
5989 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005990 // We may have already annotated macro names inside macro definitions.
5991 if (Cursors[I].kind != CXCursor_MacroExpansion)
5992 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005993 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005994 continue;
5995 }
5996 break;
5997 }
5998
5999 // Save the preprocessing token index; restore the non-preprocessing
6000 // token index.
6001 PreprocessingTokIdx = TokIdx;
6002 TokIdx = SavedTokIdx;
6003 return CXChildVisit_Recurse;
6004 }
6005
6006 if (cursorRange.isInvalid())
6007 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006008
6009 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00006010 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006011 const enum CXCursorKind K = clang_getCursorKind(parent);
6012 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006013 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
6014 // Attributes are annotated out-of-order, skip tokens until we reach it.
6015 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00006016 ? clang_getNullCursor() : parent;
6017
6018 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
6019
6020 // Avoid having the cursor of an expression "overwrite" the annotation of the
6021 // variable declaration that it belongs to.
6022 // This can happen for C++ constructor expressions whose range generally
6023 // include the variable declaration, e.g.:
6024 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006025 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00006026 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00006027 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006028 const unsigned I = NextToken();
6029 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
6030 E->getLocStart() == D->getLocation() &&
6031 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006032 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00006033 AdvanceToken();
6034 }
6035 }
6036 }
6037
6038 // Before recursing into the children keep some state that we are going
6039 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
6040 // extra work after the child nodes are visited.
6041 // Note that we don't call VisitChildren here to avoid traversing statements
6042 // code-recursively which can blow the stack.
6043
6044 PostChildrenInfo Info;
6045 Info.Cursor = cursor;
6046 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006047 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006048 Info.BeforeChildrenTokenIdx = NextToken();
6049 PostChildrenInfos.push_back(Info);
6050
6051 return CXChildVisit_Recurse;
6052}
6053
6054bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
6055 if (PostChildrenInfos.empty())
6056 return false;
6057 const PostChildrenInfo &Info = PostChildrenInfos.back();
6058 if (!clang_equalCursors(Info.Cursor, cursor))
6059 return false;
6060
6061 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
6062 const unsigned AfterChildren = NextToken();
6063 SourceRange cursorRange = Info.CursorRange;
6064
6065 // Scan the tokens that are at the end of the cursor, but are not captured
6066 // but the child cursors.
6067 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
6068
6069 // Scan the tokens that are at the beginning of the cursor, but are not
6070 // capture by the child cursors.
6071 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
6072 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
6073 break;
6074
6075 Cursors[I] = cursor;
6076 }
6077
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006078 // Attributes are annotated out-of-order, rewind TokIdx to when we first
6079 // encountered the attribute cursor.
6080 if (clang_isAttribute(cursor.kind))
6081 TokIdx = Info.BeforeReachingCursorIdx;
6082
Guy Benyei11169dd2012-12-18 14:30:41 +00006083 PostChildrenInfos.pop_back();
6084 return false;
6085}
6086
6087static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
6088 CXCursor parent,
6089 CXClientData client_data) {
6090 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
6091}
6092
6093static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
6094 CXClientData client_data) {
6095 return static_cast<AnnotateTokensWorker*>(client_data)->
6096 postVisitChildren(cursor);
6097}
6098
6099namespace {
6100
6101/// \brief Uses the macro expansions in the preprocessing record to find
6102/// and mark tokens that are macro arguments. This info is used by the
6103/// AnnotateTokensWorker.
6104class MarkMacroArgTokensVisitor {
6105 SourceManager &SM;
6106 CXToken *Tokens;
6107 unsigned NumTokens;
6108 unsigned CurIdx;
6109
6110public:
6111 MarkMacroArgTokensVisitor(SourceManager &SM,
6112 CXToken *tokens, unsigned numTokens)
6113 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
6114
6115 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
6116 if (cursor.kind != CXCursor_MacroExpansion)
6117 return CXChildVisit_Continue;
6118
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006119 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00006120 if (macroRange.getBegin() == macroRange.getEnd())
6121 return CXChildVisit_Continue; // it's not a function macro.
6122
6123 for (; CurIdx < NumTokens; ++CurIdx) {
6124 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
6125 macroRange.getBegin()))
6126 break;
6127 }
6128
6129 if (CurIdx == NumTokens)
6130 return CXChildVisit_Break;
6131
6132 for (; CurIdx < NumTokens; ++CurIdx) {
6133 SourceLocation tokLoc = getTokenLoc(CurIdx);
6134 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
6135 break;
6136
6137 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
6138 }
6139
6140 if (CurIdx == NumTokens)
6141 return CXChildVisit_Break;
6142
6143 return CXChildVisit_Continue;
6144 }
6145
6146private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006147 CXToken &getTok(unsigned Idx) {
6148 assert(Idx < NumTokens);
6149 return Tokens[Idx];
6150 }
6151 const CXToken &getTok(unsigned Idx) const {
6152 assert(Idx < NumTokens);
6153 return Tokens[Idx];
6154 }
6155
Guy Benyei11169dd2012-12-18 14:30:41 +00006156 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006157 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006158 }
6159
6160 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
6161 // The third field is reserved and currently not used. Use it here
6162 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006163 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00006164 }
6165};
6166
6167} // end anonymous namespace
6168
6169static CXChildVisitResult
6170MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
6171 CXClientData client_data) {
6172 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
6173 parent);
6174}
6175
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006176/// \brief Used by \c annotatePreprocessorTokens.
6177/// \returns true if lexing was finished, false otherwise.
6178static bool lexNext(Lexer &Lex, Token &Tok,
6179 unsigned &NextIdx, unsigned NumTokens) {
6180 if (NextIdx >= NumTokens)
6181 return true;
6182
6183 ++NextIdx;
6184 Lex.LexFromRawLexer(Tok);
6185 if (Tok.is(tok::eof))
6186 return true;
6187
6188 return false;
6189}
6190
Guy Benyei11169dd2012-12-18 14:30:41 +00006191static void annotatePreprocessorTokens(CXTranslationUnit TU,
6192 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006193 CXCursor *Cursors,
6194 CXToken *Tokens,
6195 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006196 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006197
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006198 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00006199 SourceManager &SourceMgr = CXXUnit->getSourceManager();
6200 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006201 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00006202 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006203 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00006204
6205 if (BeginLocInfo.first != EndLocInfo.first)
6206 return;
6207
6208 StringRef Buffer;
6209 bool Invalid = false;
6210 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
6211 if (Buffer.empty() || Invalid)
6212 return;
6213
6214 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
6215 CXXUnit->getASTContext().getLangOpts(),
6216 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
6217 Buffer.end());
6218 Lex.SetCommentRetentionState(true);
6219
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006220 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006221 // Lex tokens in raw mode until we hit the end of the range, to avoid
6222 // entering #includes or expanding macros.
6223 while (true) {
6224 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006225 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6226 break;
6227 unsigned TokIdx = NextIdx-1;
6228 assert(Tok.getLocation() ==
6229 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006230
6231 reprocess:
6232 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006233 // We have found a preprocessing directive. Annotate the tokens
6234 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00006235 //
6236 // FIXME: Some simple tests here could identify macro definitions and
6237 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006238
6239 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006240 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6241 break;
6242
Craig Topper69186e72014-06-08 08:38:04 +00006243 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00006244 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006245 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6246 break;
6247
6248 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00006249 IdentifierInfo &II =
6250 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006251 SourceLocation MappedTokLoc =
6252 CXXUnit->mapLocationToPreamble(Tok.getLocation());
6253 MI = getMacroInfo(II, MappedTokLoc, TU);
6254 }
6255 }
6256
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006257 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00006258 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006259 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
6260 finished = true;
6261 break;
6262 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006263 // If we are in a macro definition, check if the token was ever a
6264 // macro name and annotate it if that's the case.
6265 if (MI) {
6266 SourceLocation SaveLoc = Tok.getLocation();
6267 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
Richard Smith66a81862015-05-04 02:25:31 +00006268 MacroDefinitionRecord *MacroDef =
6269 checkForMacroInMacroDefinition(MI, Tok, TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006270 Tok.setLocation(SaveLoc);
6271 if (MacroDef)
Richard Smith66a81862015-05-04 02:25:31 +00006272 Cursors[NextIdx - 1] =
6273 MakeMacroExpansionCursor(MacroDef, Tok.getLocation(), TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006274 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006275 } while (!Tok.isAtStartOfLine());
6276
6277 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
6278 assert(TokIdx <= LastIdx);
6279 SourceLocation EndLoc =
6280 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
6281 CXCursor Cursor =
6282 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
6283
6284 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006285 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006286
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006287 if (finished)
6288 break;
6289 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00006290 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006291 }
6292}
6293
6294// This gets run a separate thread to avoid stack blowout.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006295static void clang_annotateTokensImpl(CXTranslationUnit TU, ASTUnit *CXXUnit,
6296 CXToken *Tokens, unsigned NumTokens,
6297 CXCursor *Cursors) {
Dmitri Gribenko183436e2013-01-26 21:49:50 +00006298 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006299 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
6300 setThreadBackgroundPriority();
6301
6302 // Determine the region of interest, which contains all of the tokens.
6303 SourceRange RegionOfInterest;
6304 RegionOfInterest.setBegin(
6305 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
6306 RegionOfInterest.setEnd(
6307 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
6308 Tokens[NumTokens-1])));
6309
Guy Benyei11169dd2012-12-18 14:30:41 +00006310 // Relex the tokens within the source range to look for preprocessing
6311 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006312 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006313
6314 // If begin location points inside a macro argument, set it to the expansion
6315 // location so we can have the full context when annotating semantically.
6316 {
6317 SourceManager &SM = CXXUnit->getSourceManager();
6318 SourceLocation Loc =
6319 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
6320 if (Loc.isMacroID())
6321 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
6322 }
6323
Guy Benyei11169dd2012-12-18 14:30:41 +00006324 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
6325 // Search and mark tokens that are macro argument expansions.
6326 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
6327 Tokens, NumTokens);
6328 CursorVisitor MacroArgMarker(TU,
6329 MarkMacroArgTokensVisitorDelegate, &Visitor,
6330 /*VisitPreprocessorLast=*/true,
6331 /*VisitIncludedEntities=*/false,
6332 RegionOfInterest);
6333 MacroArgMarker.visitPreprocessedEntitiesInRegion();
6334 }
6335
6336 // Annotate all of the source locations in the region of interest that map to
6337 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006338 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00006339
6340 // FIXME: We use a ridiculous stack size here because the data-recursion
6341 // algorithm uses a large stack frame than the non-data recursive version,
6342 // and AnnotationTokensWorker currently transforms the data-recursion
6343 // algorithm back into a traditional recursion by explicitly calling
6344 // VisitChildren(). We will need to remove this explicit recursive call.
6345 W.AnnotateTokens();
6346
6347 // If we ran into any entities that involve context-sensitive keywords,
6348 // take another pass through the tokens to mark them as such.
6349 if (W.hasContextSensitiveKeywords()) {
6350 for (unsigned I = 0; I != NumTokens; ++I) {
6351 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
6352 continue;
6353
6354 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
6355 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006356 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006357 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
6358 if (Property->getPropertyAttributesAsWritten() != 0 &&
6359 llvm::StringSwitch<bool>(II->getName())
6360 .Case("readonly", true)
6361 .Case("assign", true)
6362 .Case("unsafe_unretained", true)
6363 .Case("readwrite", true)
6364 .Case("retain", true)
6365 .Case("copy", true)
6366 .Case("nonatomic", true)
6367 .Case("atomic", true)
6368 .Case("getter", true)
6369 .Case("setter", true)
6370 .Case("strong", true)
6371 .Case("weak", true)
6372 .Default(false))
6373 Tokens[I].int_data[0] = CXToken_Keyword;
6374 }
6375 continue;
6376 }
6377
6378 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6379 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6380 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6381 if (llvm::StringSwitch<bool>(II->getName())
6382 .Case("in", true)
6383 .Case("out", true)
6384 .Case("inout", true)
6385 .Case("oneway", true)
6386 .Case("bycopy", true)
6387 .Case("byref", true)
6388 .Default(false))
6389 Tokens[I].int_data[0] = CXToken_Keyword;
6390 continue;
6391 }
6392
6393 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6394 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6395 Tokens[I].int_data[0] = CXToken_Keyword;
6396 continue;
6397 }
6398 }
6399 }
6400}
6401
6402extern "C" {
6403
6404void clang_annotateTokens(CXTranslationUnit TU,
6405 CXToken *Tokens, unsigned NumTokens,
6406 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006407 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006408 LOG_BAD_TU(TU);
6409 return;
6410 }
6411 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006412 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006413 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006414 }
6415
6416 LOG_FUNC_SECTION {
6417 *Log << TU << ' ';
6418 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6419 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6420 *Log << clang_getRange(bloc, eloc);
6421 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006422
6423 // Any token we don't specifically annotate will have a NULL cursor.
6424 CXCursor C = clang_getNullCursor();
6425 for (unsigned I = 0; I != NumTokens; ++I)
6426 Cursors[I] = C;
6427
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006428 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006429 if (!CXXUnit)
6430 return;
6431
6432 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006433
6434 auto AnnotateTokensImpl = [=]() {
6435 clang_annotateTokensImpl(TU, CXXUnit, Tokens, NumTokens, Cursors);
6436 };
Guy Benyei11169dd2012-12-18 14:30:41 +00006437 llvm::CrashRecoveryContext CRC;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006438 if (!RunSafely(CRC, AnnotateTokensImpl, GetSafetyThreadStackSize() * 2)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006439 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6440 }
6441}
6442
6443} // end: extern "C"
6444
6445//===----------------------------------------------------------------------===//
6446// Operations for querying linkage of a cursor.
6447//===----------------------------------------------------------------------===//
6448
6449extern "C" {
6450CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6451 if (!clang_isDeclaration(cursor.kind))
6452 return CXLinkage_Invalid;
6453
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006454 const Decl *D = cxcursor::getCursorDecl(cursor);
6455 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006456 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006457 case NoLinkage:
6458 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006459 case InternalLinkage: return CXLinkage_Internal;
6460 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6461 case ExternalLinkage: return CXLinkage_External;
6462 };
6463
6464 return CXLinkage_Invalid;
6465}
6466} // end: extern "C"
6467
6468//===----------------------------------------------------------------------===//
Ehsan Akhgari93697fa2015-11-23 19:56:46 +00006469// Operations for querying visibility of a cursor.
6470//===----------------------------------------------------------------------===//
6471
6472extern "C" {
6473CXVisibilityKind clang_getCursorVisibility(CXCursor cursor) {
6474 if (!clang_isDeclaration(cursor.kind))
6475 return CXVisibility_Invalid;
6476
6477 const Decl *D = cxcursor::getCursorDecl(cursor);
6478 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
6479 switch (ND->getVisibility()) {
6480 case HiddenVisibility: return CXVisibility_Hidden;
6481 case ProtectedVisibility: return CXVisibility_Protected;
6482 case DefaultVisibility: return CXVisibility_Default;
6483 };
6484
6485 return CXVisibility_Invalid;
6486}
6487} // end: extern "C"
6488
6489//===----------------------------------------------------------------------===//
Guy Benyei11169dd2012-12-18 14:30:41 +00006490// Operations for querying language of a cursor.
6491//===----------------------------------------------------------------------===//
6492
6493static CXLanguageKind getDeclLanguage(const Decl *D) {
6494 if (!D)
6495 return CXLanguage_C;
6496
6497 switch (D->getKind()) {
6498 default:
6499 break;
6500 case Decl::ImplicitParam:
6501 case Decl::ObjCAtDefsField:
6502 case Decl::ObjCCategory:
6503 case Decl::ObjCCategoryImpl:
6504 case Decl::ObjCCompatibleAlias:
6505 case Decl::ObjCImplementation:
6506 case Decl::ObjCInterface:
6507 case Decl::ObjCIvar:
6508 case Decl::ObjCMethod:
6509 case Decl::ObjCProperty:
6510 case Decl::ObjCPropertyImpl:
6511 case Decl::ObjCProtocol:
Douglas Gregor85f3f952015-07-07 03:57:15 +00006512 case Decl::ObjCTypeParam:
Guy Benyei11169dd2012-12-18 14:30:41 +00006513 return CXLanguage_ObjC;
6514 case Decl::CXXConstructor:
6515 case Decl::CXXConversion:
6516 case Decl::CXXDestructor:
6517 case Decl::CXXMethod:
6518 case Decl::CXXRecord:
6519 case Decl::ClassTemplate:
6520 case Decl::ClassTemplatePartialSpecialization:
6521 case Decl::ClassTemplateSpecialization:
6522 case Decl::Friend:
6523 case Decl::FriendTemplate:
6524 case Decl::FunctionTemplate:
6525 case Decl::LinkageSpec:
6526 case Decl::Namespace:
6527 case Decl::NamespaceAlias:
6528 case Decl::NonTypeTemplateParm:
6529 case Decl::StaticAssert:
6530 case Decl::TemplateTemplateParm:
6531 case Decl::TemplateTypeParm:
6532 case Decl::UnresolvedUsingTypename:
6533 case Decl::UnresolvedUsingValue:
6534 case Decl::Using:
6535 case Decl::UsingDirective:
6536 case Decl::UsingShadow:
6537 return CXLanguage_CPlusPlus;
6538 }
6539
6540 return CXLanguage_C;
6541}
6542
6543extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006544
6545static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6546 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
Manuel Klimek8e3a7ed2015-09-25 17:53:16 +00006547 return CXAvailability_NotAvailable;
Guy Benyei11169dd2012-12-18 14:30:41 +00006548
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006549 switch (D->getAvailability()) {
6550 case AR_Available:
6551 case AR_NotYetIntroduced:
6552 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006553 return getCursorAvailabilityForDecl(
6554 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006555 return CXAvailability_Available;
6556
6557 case AR_Deprecated:
6558 return CXAvailability_Deprecated;
6559
6560 case AR_Unavailable:
6561 return CXAvailability_NotAvailable;
6562 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006563
6564 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006565}
6566
Guy Benyei11169dd2012-12-18 14:30:41 +00006567enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6568 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006569 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6570 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006571
6572 return CXAvailability_Available;
6573}
6574
6575static CXVersion convertVersion(VersionTuple In) {
6576 CXVersion Out = { -1, -1, -1 };
6577 if (In.empty())
6578 return Out;
6579
6580 Out.Major = In.getMajor();
6581
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006582 Optional<unsigned> Minor = In.getMinor();
6583 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006584 Out.Minor = *Minor;
6585 else
6586 return Out;
6587
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006588 Optional<unsigned> Subminor = In.getSubminor();
6589 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006590 Out.Subminor = *Subminor;
6591
6592 return Out;
6593}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006594
6595static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6596 int *always_deprecated,
6597 CXString *deprecated_message,
6598 int *always_unavailable,
6599 CXString *unavailable_message,
6600 CXPlatformAvailability *availability,
6601 int availability_size) {
6602 bool HadAvailAttr = false;
6603 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006604 for (auto A : D->attrs()) {
6605 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006606 HadAvailAttr = true;
6607 if (always_deprecated)
6608 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006609 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006610 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006611 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006612 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006613 continue;
6614 }
6615
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006616 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006617 HadAvailAttr = true;
6618 if (always_unavailable)
6619 *always_unavailable = 1;
6620 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006621 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006622 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6623 }
6624 continue;
6625 }
6626
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006627 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006628 HadAvailAttr = true;
6629 if (N < availability_size) {
6630 availability[N].Platform
6631 = cxstring::createDup(Avail->getPlatform()->getName());
6632 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6633 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6634 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6635 availability[N].Unavailable = Avail->getUnavailable();
6636 availability[N].Message = cxstring::createDup(Avail->getMessage());
6637 }
6638 ++N;
6639 }
6640 }
6641
6642 if (!HadAvailAttr)
6643 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6644 return getCursorPlatformAvailabilityForDecl(
6645 cast<Decl>(EnumConst->getDeclContext()),
6646 always_deprecated,
6647 deprecated_message,
6648 always_unavailable,
6649 unavailable_message,
6650 availability,
6651 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006652
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006653 return N;
6654}
6655
Guy Benyei11169dd2012-12-18 14:30:41 +00006656int clang_getCursorPlatformAvailability(CXCursor cursor,
6657 int *always_deprecated,
6658 CXString *deprecated_message,
6659 int *always_unavailable,
6660 CXString *unavailable_message,
6661 CXPlatformAvailability *availability,
6662 int availability_size) {
6663 if (always_deprecated)
6664 *always_deprecated = 0;
6665 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006666 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006667 if (always_unavailable)
6668 *always_unavailable = 0;
6669 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006670 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006671
Guy Benyei11169dd2012-12-18 14:30:41 +00006672 if (!clang_isDeclaration(cursor.kind))
6673 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006674
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006675 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006676 if (!D)
6677 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006678
6679 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6680 deprecated_message,
6681 always_unavailable,
6682 unavailable_message,
6683 availability,
6684 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006685}
6686
6687void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6688 clang_disposeString(availability->Platform);
6689 clang_disposeString(availability->Message);
6690}
6691
6692CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6693 if (clang_isDeclaration(cursor.kind))
6694 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6695
6696 return CXLanguage_Invalid;
6697}
6698
6699 /// \brief If the given cursor is the "templated" declaration
6700 /// descibing a class or function template, return the class or
6701 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006702static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006703 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006704 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006705
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006706 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006707 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6708 return FunTmpl;
6709
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006710 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006711 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6712 return ClassTmpl;
6713
6714 return D;
6715}
6716
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006717
6718enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
6719 StorageClass sc = SC_None;
6720 const Decl *D = getCursorDecl(C);
6721 if (D) {
6722 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
6723 sc = FD->getStorageClass();
6724 } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
6725 sc = VD->getStorageClass();
6726 } else {
6727 return CX_SC_Invalid;
6728 }
6729 } else {
6730 return CX_SC_Invalid;
6731 }
6732 switch (sc) {
6733 case SC_None:
6734 return CX_SC_None;
6735 case SC_Extern:
6736 return CX_SC_Extern;
6737 case SC_Static:
6738 return CX_SC_Static;
6739 case SC_PrivateExtern:
6740 return CX_SC_PrivateExtern;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006741 case SC_Auto:
6742 return CX_SC_Auto;
6743 case SC_Register:
6744 return CX_SC_Register;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006745 }
Kaelyn Takataab61e702014-10-15 18:03:26 +00006746 llvm_unreachable("Unhandled storage class!");
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006747}
6748
Guy Benyei11169dd2012-12-18 14:30:41 +00006749CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6750 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006751 if (const Decl *D = getCursorDecl(cursor)) {
6752 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006753 if (!DC)
6754 return clang_getNullCursor();
6755
6756 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6757 getCursorTU(cursor));
6758 }
6759 }
6760
6761 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006762 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006763 return MakeCXCursor(D, getCursorTU(cursor));
6764 }
6765
6766 return clang_getNullCursor();
6767}
6768
6769CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6770 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006771 if (const Decl *D = getCursorDecl(cursor)) {
6772 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006773 if (!DC)
6774 return clang_getNullCursor();
6775
6776 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6777 getCursorTU(cursor));
6778 }
6779 }
6780
6781 // FIXME: Note that we can't easily compute the lexical context of a
6782 // statement or expression, so we return nothing.
6783 return clang_getNullCursor();
6784}
6785
6786CXFile clang_getIncludedFile(CXCursor cursor) {
6787 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006788 return nullptr;
6789
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006790 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006791 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006792}
6793
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006794unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6795 if (C.kind != CXCursor_ObjCPropertyDecl)
6796 return CXObjCPropertyAttr_noattr;
6797
6798 unsigned Result = CXObjCPropertyAttr_noattr;
6799 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6800 ObjCPropertyDecl::PropertyAttributeKind Attr =
6801 PD->getPropertyAttributesAsWritten();
6802
6803#define SET_CXOBJCPROP_ATTR(A) \
6804 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6805 Result |= CXObjCPropertyAttr_##A
6806 SET_CXOBJCPROP_ATTR(readonly);
6807 SET_CXOBJCPROP_ATTR(getter);
6808 SET_CXOBJCPROP_ATTR(assign);
6809 SET_CXOBJCPROP_ATTR(readwrite);
6810 SET_CXOBJCPROP_ATTR(retain);
6811 SET_CXOBJCPROP_ATTR(copy);
6812 SET_CXOBJCPROP_ATTR(nonatomic);
6813 SET_CXOBJCPROP_ATTR(setter);
6814 SET_CXOBJCPROP_ATTR(atomic);
6815 SET_CXOBJCPROP_ATTR(weak);
6816 SET_CXOBJCPROP_ATTR(strong);
6817 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6818#undef SET_CXOBJCPROP_ATTR
6819
6820 return Result;
6821}
6822
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006823unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6824 if (!clang_isDeclaration(C.kind))
6825 return CXObjCDeclQualifier_None;
6826
6827 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6828 const Decl *D = getCursorDecl(C);
6829 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6830 QT = MD->getObjCDeclQualifier();
6831 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6832 QT = PD->getObjCDeclQualifier();
6833 if (QT == Decl::OBJC_TQ_None)
6834 return CXObjCDeclQualifier_None;
6835
6836 unsigned Result = CXObjCDeclQualifier_None;
6837 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6838 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6839 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6840 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6841 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6842 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6843
6844 return Result;
6845}
6846
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006847unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6848 if (!clang_isDeclaration(C.kind))
6849 return 0;
6850
6851 const Decl *D = getCursorDecl(C);
6852 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6853 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6854 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6855 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6856
6857 return 0;
6858}
6859
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006860unsigned clang_Cursor_isVariadic(CXCursor C) {
6861 if (!clang_isDeclaration(C.kind))
6862 return 0;
6863
6864 const Decl *D = getCursorDecl(C);
6865 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6866 return FD->isVariadic();
6867 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6868 return MD->isVariadic();
6869
6870 return 0;
6871}
6872
Guy Benyei11169dd2012-12-18 14:30:41 +00006873CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6874 if (!clang_isDeclaration(C.kind))
6875 return clang_getNullRange();
6876
6877 const Decl *D = getCursorDecl(C);
6878 ASTContext &Context = getCursorContext(C);
6879 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6880 if (!RC)
6881 return clang_getNullRange();
6882
6883 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6884}
6885
6886CXString clang_Cursor_getRawCommentText(CXCursor C) {
6887 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006888 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006889
6890 const Decl *D = getCursorDecl(C);
6891 ASTContext &Context = getCursorContext(C);
6892 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6893 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6894 StringRef();
6895
6896 // Don't duplicate the string because RawText points directly into source
6897 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006898 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006899}
6900
6901CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6902 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006903 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006904
6905 const Decl *D = getCursorDecl(C);
6906 const ASTContext &Context = getCursorContext(C);
6907 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6908
6909 if (RC) {
6910 StringRef BriefText = RC->getBriefText(Context);
6911
6912 // Don't duplicate the string because RawComment ensures that this memory
6913 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006914 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006915 }
6916
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006917 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006918}
6919
Guy Benyei11169dd2012-12-18 14:30:41 +00006920CXModule clang_Cursor_getModule(CXCursor C) {
6921 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006922 if (const ImportDecl *ImportD =
6923 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006924 return ImportD->getImportedModule();
6925 }
6926
Craig Topper69186e72014-06-08 08:38:04 +00006927 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006928}
6929
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006930CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6931 if (isNotUsableTU(TU)) {
6932 LOG_BAD_TU(TU);
6933 return nullptr;
6934 }
6935 if (!File)
6936 return nullptr;
6937 FileEntry *FE = static_cast<FileEntry *>(File);
6938
6939 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6940 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6941 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6942
Richard Smithfeb54b62014-10-23 02:01:19 +00006943 return Header.getModule();
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006944}
6945
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006946CXFile clang_Module_getASTFile(CXModule CXMod) {
6947 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006948 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006949 Module *Mod = static_cast<Module*>(CXMod);
6950 return const_cast<FileEntry *>(Mod->getASTFile());
6951}
6952
Guy Benyei11169dd2012-12-18 14:30:41 +00006953CXModule clang_Module_getParent(CXModule CXMod) {
6954 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006955 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006956 Module *Mod = static_cast<Module*>(CXMod);
6957 return Mod->Parent;
6958}
6959
6960CXString clang_Module_getName(CXModule CXMod) {
6961 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006962 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006963 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006964 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006965}
6966
6967CXString clang_Module_getFullName(CXModule CXMod) {
6968 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006969 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006970 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006971 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006972}
6973
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006974int clang_Module_isSystem(CXModule CXMod) {
6975 if (!CXMod)
6976 return 0;
6977 Module *Mod = static_cast<Module*>(CXMod);
6978 return Mod->IsSystem;
6979}
6980
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006981unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6982 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006983 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006984 LOG_BAD_TU(TU);
6985 return 0;
6986 }
6987 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006988 return 0;
6989 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006990 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6991 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6992 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006993}
6994
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006995CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6996 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006997 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006998 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006999 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007000 }
7001 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00007002 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007003 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007004 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00007005
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007006 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
7007 if (Index < TopHeaders.size())
7008 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00007009
Craig Topper69186e72014-06-08 08:38:04 +00007010 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007011}
7012
7013} // end: extern "C"
7014
7015//===----------------------------------------------------------------------===//
7016// C++ AST instrospection.
7017//===----------------------------------------------------------------------===//
7018
7019extern "C" {
Saleem Abdulrasool6ea75db2015-10-27 15:50:22 +00007020unsigned clang_CXXField_isMutable(CXCursor C) {
7021 if (!clang_isDeclaration(C.kind))
7022 return 0;
7023
7024 if (const auto D = cxcursor::getCursorDecl(C))
7025 if (const auto FD = dyn_cast_or_null<FieldDecl>(D))
7026 return FD->isMutable() ? 1 : 0;
7027 return 0;
7028}
7029
Dmitri Gribenko62770be2013-05-17 18:38:35 +00007030unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
7031 if (!clang_isDeclaration(C.kind))
7032 return 0;
7033
Dmitri Gribenko62770be2013-05-17 18:38:35 +00007034 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007035 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007036 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00007037 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
7038}
7039
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00007040unsigned clang_CXXMethod_isConst(CXCursor C) {
7041 if (!clang_isDeclaration(C.kind))
7042 return 0;
7043
7044 const Decl *D = cxcursor::getCursorDecl(C);
7045 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007046 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00007047 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
7048}
7049
Guy Benyei11169dd2012-12-18 14:30:41 +00007050unsigned clang_CXXMethod_isStatic(CXCursor C) {
7051 if (!clang_isDeclaration(C.kind))
7052 return 0;
7053
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007054 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007055 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007056 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007057 return (Method && Method->isStatic()) ? 1 : 0;
7058}
7059
7060unsigned clang_CXXMethod_isVirtual(CXCursor C) {
7061 if (!clang_isDeclaration(C.kind))
7062 return 0;
7063
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007064 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007065 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007066 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007067 return (Method && Method->isVirtual()) ? 1 : 0;
7068}
7069} // end: extern "C"
7070
7071//===----------------------------------------------------------------------===//
7072// Attribute introspection.
7073//===----------------------------------------------------------------------===//
7074
7075extern "C" {
7076CXType clang_getIBOutletCollectionType(CXCursor C) {
7077 if (C.kind != CXCursor_IBOutletCollectionAttr)
7078 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
7079
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00007080 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00007081 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
7082
7083 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
7084}
7085} // end: extern "C"
7086
7087//===----------------------------------------------------------------------===//
7088// Inspecting memory usage.
7089//===----------------------------------------------------------------------===//
7090
7091typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
7092
7093static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
7094 enum CXTUResourceUsageKind k,
7095 unsigned long amount) {
7096 CXTUResourceUsageEntry entry = { k, amount };
7097 entries.push_back(entry);
7098}
7099
7100extern "C" {
7101
7102const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
7103 const char *str = "";
7104 switch (kind) {
7105 case CXTUResourceUsage_AST:
7106 str = "ASTContext: expressions, declarations, and types";
7107 break;
7108 case CXTUResourceUsage_Identifiers:
7109 str = "ASTContext: identifiers";
7110 break;
7111 case CXTUResourceUsage_Selectors:
7112 str = "ASTContext: selectors";
7113 break;
7114 case CXTUResourceUsage_GlobalCompletionResults:
7115 str = "Code completion: cached global results";
7116 break;
7117 case CXTUResourceUsage_SourceManagerContentCache:
7118 str = "SourceManager: content cache allocator";
7119 break;
7120 case CXTUResourceUsage_AST_SideTables:
7121 str = "ASTContext: side tables";
7122 break;
7123 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
7124 str = "SourceManager: malloc'ed memory buffers";
7125 break;
7126 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
7127 str = "SourceManager: mmap'ed memory buffers";
7128 break;
7129 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
7130 str = "ExternalASTSource: malloc'ed memory buffers";
7131 break;
7132 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
7133 str = "ExternalASTSource: mmap'ed memory buffers";
7134 break;
7135 case CXTUResourceUsage_Preprocessor:
7136 str = "Preprocessor: malloc'ed memory";
7137 break;
7138 case CXTUResourceUsage_PreprocessingRecord:
7139 str = "Preprocessor: PreprocessingRecord";
7140 break;
7141 case CXTUResourceUsage_SourceManager_DataStructures:
7142 str = "SourceManager: data structures and tables";
7143 break;
7144 case CXTUResourceUsage_Preprocessor_HeaderSearch:
7145 str = "Preprocessor: header search tables";
7146 break;
7147 }
7148 return str;
7149}
7150
7151CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007152 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007153 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00007154 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00007155 return usage;
7156 }
7157
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007158 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00007159 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00007160 ASTContext &astContext = astUnit->getASTContext();
7161
7162 // How much memory is used by AST nodes and types?
7163 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
7164 (unsigned long) astContext.getASTAllocatedMemory());
7165
7166 // How much memory is used by identifiers?
7167 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
7168 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
7169
7170 // How much memory is used for selectors?
7171 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
7172 (unsigned long) astContext.Selectors.getTotalMemory());
7173
7174 // How much memory is used by ASTContext's side tables?
7175 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
7176 (unsigned long) astContext.getSideTableAllocatedMemory());
7177
7178 // How much memory is used for caching global code completion results?
7179 unsigned long completionBytes = 0;
7180 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00007181 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007182 completionBytes = completionAllocator->getTotalMemory();
7183 }
7184 createCXTUResourceUsageEntry(*entries,
7185 CXTUResourceUsage_GlobalCompletionResults,
7186 completionBytes);
7187
7188 // How much memory is being used by SourceManager's content cache?
7189 createCXTUResourceUsageEntry(*entries,
7190 CXTUResourceUsage_SourceManagerContentCache,
7191 (unsigned long) astContext.getSourceManager().getContentCacheSize());
7192
7193 // How much memory is being used by the MemoryBuffer's in SourceManager?
7194 const SourceManager::MemoryBufferSizes &srcBufs =
7195 astUnit->getSourceManager().getMemoryBufferSizes();
7196
7197 createCXTUResourceUsageEntry(*entries,
7198 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
7199 (unsigned long) srcBufs.malloc_bytes);
7200 createCXTUResourceUsageEntry(*entries,
7201 CXTUResourceUsage_SourceManager_Membuffer_MMap,
7202 (unsigned long) srcBufs.mmap_bytes);
7203 createCXTUResourceUsageEntry(*entries,
7204 CXTUResourceUsage_SourceManager_DataStructures,
7205 (unsigned long) astContext.getSourceManager()
7206 .getDataStructureSizes());
7207
7208 // How much memory is being used by the ExternalASTSource?
7209 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
7210 const ExternalASTSource::MemoryBufferSizes &sizes =
7211 esrc->getMemoryBufferSizes();
7212
7213 createCXTUResourceUsageEntry(*entries,
7214 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
7215 (unsigned long) sizes.malloc_bytes);
7216 createCXTUResourceUsageEntry(*entries,
7217 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
7218 (unsigned long) sizes.mmap_bytes);
7219 }
7220
7221 // How much memory is being used by the Preprocessor?
7222 Preprocessor &pp = astUnit->getPreprocessor();
7223 createCXTUResourceUsageEntry(*entries,
7224 CXTUResourceUsage_Preprocessor,
7225 pp.getTotalMemory());
7226
7227 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
7228 createCXTUResourceUsageEntry(*entries,
7229 CXTUResourceUsage_PreprocessingRecord,
7230 pRec->getTotalMemory());
7231 }
7232
7233 createCXTUResourceUsageEntry(*entries,
7234 CXTUResourceUsage_Preprocessor_HeaderSearch,
7235 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00007236
Guy Benyei11169dd2012-12-18 14:30:41 +00007237 CXTUResourceUsage usage = { (void*) entries.get(),
7238 (unsigned) entries->size(),
Alexander Kornienko6ee521c2015-01-23 15:36:10 +00007239 !entries->empty() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00007240 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00007241 return usage;
7242}
7243
7244void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
7245 if (usage.data)
7246 delete (MemUsageEntries*) usage.data;
7247}
7248
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007249CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
7250 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007251 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00007252 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007253
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007254 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007255 LOG_BAD_TU(TU);
7256 return skipped;
7257 }
7258
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007259 if (!file)
7260 return skipped;
7261
7262 ASTUnit *astUnit = cxtu::getASTUnit(TU);
7263 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
7264 if (!ppRec)
7265 return skipped;
7266
7267 ASTContext &Ctx = astUnit->getASTContext();
7268 SourceManager &sm = Ctx.getSourceManager();
7269 FileEntry *fileEntry = static_cast<FileEntry *>(file);
7270 FileID wantedFileID = sm.translateFile(fileEntry);
7271
7272 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
7273 std::vector<SourceRange> wantedRanges;
7274 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
7275 i != ei; ++i) {
7276 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
7277 wantedRanges.push_back(*i);
7278 }
7279
7280 skipped->count = wantedRanges.size();
7281 skipped->ranges = new CXSourceRange[skipped->count];
7282 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
7283 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
7284
7285 return skipped;
7286}
7287
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007288void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
7289 if (ranges) {
7290 delete[] ranges->ranges;
7291 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007292 }
7293}
7294
Guy Benyei11169dd2012-12-18 14:30:41 +00007295} // end extern "C"
7296
7297void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
7298 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
7299 for (unsigned I = 0; I != Usage.numEntries; ++I)
7300 fprintf(stderr, " %s: %lu\n",
7301 clang_getTUResourceUsageName(Usage.entries[I].kind),
7302 Usage.entries[I].amount);
7303
7304 clang_disposeCXTUResourceUsage(Usage);
7305}
7306
7307//===----------------------------------------------------------------------===//
7308// Misc. utility functions.
7309//===----------------------------------------------------------------------===//
7310
7311/// Default to using an 8 MB stack size on "safety" threads.
7312static unsigned SafetyStackThreadSize = 8 << 20;
7313
7314namespace clang {
7315
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007316bool RunSafely(llvm::CrashRecoveryContext &CRC, llvm::function_ref<void()> Fn,
Guy Benyei11169dd2012-12-18 14:30:41 +00007317 unsigned Size) {
7318 if (!Size)
7319 Size = GetSafetyThreadStackSize();
7320 if (Size)
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007321 return CRC.RunSafelyOnThread(Fn, Size);
7322 return CRC.RunSafely(Fn);
Guy Benyei11169dd2012-12-18 14:30:41 +00007323}
7324
7325unsigned GetSafetyThreadStackSize() {
7326 return SafetyStackThreadSize;
7327}
7328
7329void SetSafetyThreadStackSize(unsigned Value) {
7330 SafetyStackThreadSize = Value;
7331}
7332
Alexander Kornienkoab9db512015-06-22 23:07:51 +00007333}
Guy Benyei11169dd2012-12-18 14:30:41 +00007334
7335void clang::setThreadBackgroundPriority() {
7336 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
7337 return;
7338
Alp Toker1a86ad22014-07-06 06:24:00 +00007339#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00007340 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
7341#endif
7342}
7343
7344void cxindex::printDiagsToStderr(ASTUnit *Unit) {
7345 if (!Unit)
7346 return;
7347
7348 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
7349 DEnd = Unit->stored_diag_end();
7350 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00007351 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00007352 CXString Msg = clang_formatDiagnostic(&Diag,
7353 clang_defaultDiagnosticDisplayOptions());
7354 fprintf(stderr, "%s\n", clang_getCString(Msg));
7355 clang_disposeString(Msg);
7356 }
7357#ifdef LLVM_ON_WIN32
7358 // On Windows, force a flush, since there may be multiple copies of
7359 // stderr and stdout in the file system, all with different buffers
7360 // but writing to the same device.
7361 fflush(stderr);
7362#endif
7363}
7364
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007365MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
7366 SourceLocation MacroDefLoc,
7367 CXTranslationUnit TU){
7368 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007369 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007370 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007371 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007372
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007373 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007374 Preprocessor &PP = Unit->getPreprocessor();
Richard Smith20e883e2015-04-29 23:20:19 +00007375 MacroDirective *MD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007376 if (MD) {
7377 for (MacroDirective::DefInfo
7378 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
7379 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
7380 return Def.getMacroInfo();
7381 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007382 }
7383
Craig Topper69186e72014-06-08 08:38:04 +00007384 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007385}
7386
Richard Smith66a81862015-05-04 02:25:31 +00007387const MacroInfo *cxindex::getMacroInfo(const MacroDefinitionRecord *MacroDef,
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007388 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007389 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007390 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007391 const IdentifierInfo *II = MacroDef->getName();
7392 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00007393 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007394
7395 return getMacroInfo(*II, MacroDef->getLocation(), TU);
7396}
7397
Richard Smith66a81862015-05-04 02:25:31 +00007398MacroDefinitionRecord *
7399cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, const Token &Tok,
7400 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007401 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007402 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007403 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00007404 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007405
7406 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007407 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007408 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
7409 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007410 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007411
7412 // Check that the token is inside the definition and not its argument list.
7413 SourceManager &SM = Unit->getSourceManager();
7414 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00007415 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007416 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00007417 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007418
7419 Preprocessor &PP = Unit->getPreprocessor();
7420 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
7421 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00007422 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007423
Alp Toker2d57cea2014-05-17 04:53:25 +00007424 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007425 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007426 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007427
7428 // Check that the identifier is not one of the macro arguments.
7429 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00007430 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007431
Richard Smith20e883e2015-04-29 23:20:19 +00007432 MacroDirective *InnerMD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007433 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00007434 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007435
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007436 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007437}
7438
Richard Smith66a81862015-05-04 02:25:31 +00007439MacroDefinitionRecord *
7440cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, SourceLocation Loc,
7441 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007442 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007443 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007444
7445 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007446 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007447 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007448 Preprocessor &PP = Unit->getPreprocessor();
7449 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00007450 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007451 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7452 Token Tok;
7453 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00007454 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007455
7456 return checkForMacroInMacroDefinition(MI, Tok, TU);
7457}
7458
Guy Benyei11169dd2012-12-18 14:30:41 +00007459extern "C" {
7460
7461CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007462 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00007463}
7464
7465} // end: extern "C"
7466
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007467Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7468 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007469 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007470 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007471 if (Unit->isMainFileAST())
7472 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007473 return *this;
7474 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007475 } else {
7476 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007477 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007478 return *this;
7479}
7480
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007481Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7482 *this << FE->getName();
7483 return *this;
7484}
7485
7486Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7487 CXString cursorName = clang_getCursorDisplayName(cursor);
7488 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7489 clang_disposeString(cursorName);
7490 return *this;
7491}
7492
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007493Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7494 CXFile File;
7495 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007496 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007497 CXString FileName = clang_getFileName(File);
7498 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7499 clang_disposeString(FileName);
7500 return *this;
7501}
7502
7503Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7504 CXSourceLocation BLoc = clang_getRangeStart(range);
7505 CXSourceLocation ELoc = clang_getRangeEnd(range);
7506
7507 CXFile BFile;
7508 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007509 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007510
7511 CXFile EFile;
7512 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007513 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007514
7515 CXString BFileName = clang_getFileName(BFile);
7516 if (BFile == EFile) {
7517 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7518 BLine, BColumn, ELine, EColumn);
7519 } else {
7520 CXString EFileName = clang_getFileName(EFile);
7521 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7522 BLine, BColumn)
7523 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7524 ELine, EColumn);
7525 clang_disposeString(EFileName);
7526 }
7527 clang_disposeString(BFileName);
7528 return *this;
7529}
7530
7531Logger &cxindex::Logger::operator<<(CXString Str) {
7532 *this << clang_getCString(Str);
7533 return *this;
7534}
7535
7536Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7537 LogOS << Fmt;
7538 return *this;
7539}
7540
Chandler Carruth37ad2582014-06-27 15:14:39 +00007541static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7542
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007543cxindex::Logger::~Logger() {
Chandler Carruth37ad2582014-06-27 15:14:39 +00007544 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007545
7546 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7547
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007548 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007549 OS << "[libclang:" << Name << ':';
7550
Alp Toker1a86ad22014-07-06 06:24:00 +00007551#ifdef USE_DARWIN_THREADS
7552 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007553 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7554 OS << tid << ':';
7555#endif
7556
7557 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7558 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
Yaron Keren09fb7c62015-03-10 07:33:23 +00007559 OS << Msg << '\n';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007560
7561 if (Trace) {
Zachary Turner1fe2a8d2015-03-05 19:15:09 +00007562 llvm::sys::PrintStackTrace(OS);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007563 OS << "--------------------------------------------------\n";
7564 }
7565}