blob: 3e51aa41878bed88c6e4d1beb9cdb40139773c41 [file] [log] [blame]
Guy Benyei11169dd2012-12-18 14:30:41 +00001//===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the main API hooks in the Clang-C Source Indexing
11// library.
12//
13//===----------------------------------------------------------------------===//
14
15#include "CIndexer.h"
16#include "CIndexDiagnostic.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000017#include "CLog.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000018#include "CXCursor.h"
19#include "CXSourceLocation.h"
20#include "CXString.h"
21#include "CXTranslationUnit.h"
22#include "CXType.h"
23#include "CursorVisitor.h"
David Blaikie0a4e61f2013-09-13 18:32:52 +000024#include "clang/AST/Attr.h"
Eli Bendersky44a206f2014-07-31 18:04:56 +000025#include "clang/AST/Mangle.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000026#include "clang/AST/StmtVisitor.h"
27#include "clang/Basic/Diagnostic.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000028#include "clang/Basic/DiagnosticCategories.h"
29#include "clang/Basic/DiagnosticIDs.h"
Eli Bendersky79759592014-08-01 15:01:10 +000030#include "clang/Basic/TargetInfo.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000031#include "clang/Basic/Version.h"
32#include "clang/Frontend/ASTUnit.h"
33#include "clang/Frontend/CompilerInstance.h"
34#include "clang/Frontend/FrontendDiagnostic.h"
Dmitri Gribenko9e605112013-11-13 22:16:51 +000035#include "clang/Index/CommentToXML.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000036#include "clang/Lex/HeaderSearch.h"
37#include "clang/Lex/Lexer.h"
38#include "clang/Lex/PreprocessingRecord.h"
39#include "clang/Lex/Preprocessor.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000040#include "clang/Serialization/SerializationDiagnostic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000041#include "llvm/ADT/Optional.h"
42#include "llvm/ADT/STLExtras.h"
43#include "llvm/ADT/StringSwitch.h"
Alp Toker1d257e12014-06-04 03:28:55 +000044#include "llvm/Config/llvm-config.h"
Eli Bendersky79759592014-08-01 15:01:10 +000045#include "llvm/IR/DataLayout.h"
46#include "llvm/IR/Mangler.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000047#include "llvm/Support/Compiler.h"
48#include "llvm/Support/CrashRecoveryContext.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000049#include "llvm/Support/Format.h"
Chandler Carruth37ad2582014-06-27 15:14:39 +000050#include "llvm/Support/ManagedStatic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000051#include "llvm/Support/MemoryBuffer.h"
52#include "llvm/Support/Mutex.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000053#include "llvm/Support/Program.h"
54#include "llvm/Support/SaveAndRestore.h"
55#include "llvm/Support/Signals.h"
Adrian Prantlbc068582015-07-08 01:00:30 +000056#include "llvm/Support/TargetSelect.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000057#include "llvm/Support/Threading.h"
58#include "llvm/Support/Timer.h"
59#include "llvm/Support/raw_ostream.h"
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000060
Alp Toker1a86ad22014-07-06 06:24:00 +000061#if LLVM_ENABLE_THREADS != 0 && defined(__APPLE__)
62#define USE_DARWIN_THREADS
63#endif
64
65#ifdef USE_DARWIN_THREADS
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000066#include <pthread.h>
67#endif
Guy Benyei11169dd2012-12-18 14:30:41 +000068
69using namespace clang;
70using namespace clang::cxcursor;
Guy Benyei11169dd2012-12-18 14:30:41 +000071using namespace clang::cxtu;
72using namespace clang::cxindex;
73
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000074CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) {
75 if (!AU)
Craig Topper69186e72014-06-08 08:38:04 +000076 return nullptr;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000077 assert(CIdx);
Guy Benyei11169dd2012-12-18 14:30:41 +000078 CXTranslationUnit D = new CXTranslationUnitImpl();
79 D->CIdx = CIdx;
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000080 D->TheASTUnit = AU;
Dmitri Gribenko74895212013-02-03 13:52:47 +000081 D->StringPool = new cxstring::CXStringPool();
Craig Topper69186e72014-06-08 08:38:04 +000082 D->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000083 D->OverridenCursorsPool = createOverridenCXCursorsPool();
Craig Topper69186e72014-06-08 08:38:04 +000084 D->CommentToXML = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000085 return D;
86}
87
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000088bool cxtu::isASTReadError(ASTUnit *AU) {
89 for (ASTUnit::stored_diag_iterator D = AU->stored_diag_begin(),
90 DEnd = AU->stored_diag_end();
91 D != DEnd; ++D) {
92 if (D->getLevel() >= DiagnosticsEngine::Error &&
93 DiagnosticIDs::getCategoryNumberForDiag(D->getID()) ==
94 diag::DiagCat_AST_Deserialization_Issue)
95 return true;
96 }
97 return false;
98}
99
Guy Benyei11169dd2012-12-18 14:30:41 +0000100cxtu::CXTUOwner::~CXTUOwner() {
101 if (TU)
102 clang_disposeTranslationUnit(TU);
103}
104
105/// \brief Compare two source ranges to determine their relative position in
106/// the translation unit.
107static RangeComparisonResult RangeCompare(SourceManager &SM,
108 SourceRange R1,
109 SourceRange R2) {
110 assert(R1.isValid() && "First range is invalid?");
111 assert(R2.isValid() && "Second range is invalid?");
112 if (R1.getEnd() != R2.getBegin() &&
113 SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
114 return RangeBefore;
115 if (R2.getEnd() != R1.getBegin() &&
116 SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
117 return RangeAfter;
118 return RangeOverlap;
119}
120
121/// \brief Determine if a source location falls within, before, or after a
122/// a given source range.
123static RangeComparisonResult LocationCompare(SourceManager &SM,
124 SourceLocation L, SourceRange R) {
125 assert(R.isValid() && "First range is invalid?");
126 assert(L.isValid() && "Second range is invalid?");
127 if (L == R.getBegin() || L == R.getEnd())
128 return RangeOverlap;
129 if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
130 return RangeBefore;
131 if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
132 return RangeAfter;
133 return RangeOverlap;
134}
135
136/// \brief Translate a Clang source range into a CIndex source range.
137///
138/// Clang internally represents ranges where the end location points to the
139/// start of the token at the end. However, for external clients it is more
140/// useful to have a CXSourceRange be a proper half-open interval. This routine
141/// does the appropriate translation.
142CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
143 const LangOptions &LangOpts,
144 const CharSourceRange &R) {
145 // We want the last character in this location, so we will adjust the
146 // location accordingly.
147 SourceLocation EndLoc = R.getEnd();
148 if (EndLoc.isValid() && EndLoc.isMacroID() && !SM.isMacroArgExpansion(EndLoc))
149 EndLoc = SM.getExpansionRange(EndLoc).second;
Yaron Keren8b563662015-10-03 10:46:20 +0000150 if (R.isTokenRange() && EndLoc.isValid()) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000151 unsigned Length = Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc),
152 SM, LangOpts);
153 EndLoc = EndLoc.getLocWithOffset(Length);
154 }
155
Bill Wendlingeade3622013-01-23 08:25:41 +0000156 CXSourceRange Result = {
Dmitri Gribenkof9304482013-01-23 15:56:07 +0000157 { &SM, &LangOpts },
Bill Wendlingeade3622013-01-23 08:25:41 +0000158 R.getBegin().getRawEncoding(),
159 EndLoc.getRawEncoding()
160 };
Guy Benyei11169dd2012-12-18 14:30:41 +0000161 return Result;
162}
163
164//===----------------------------------------------------------------------===//
165// Cursor visitor.
166//===----------------------------------------------------------------------===//
167
168static SourceRange getRawCursorExtent(CXCursor C);
169static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
170
171
172RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
173 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
174}
175
176/// \brief Visit the given cursor and, if requested by the visitor,
177/// its children.
178///
179/// \param Cursor the cursor to visit.
180///
181/// \param CheckedRegionOfInterest if true, then the caller already checked
182/// that this cursor is within the region of interest.
183///
184/// \returns true if the visitation should be aborted, false if it
185/// should continue.
186bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
187 if (clang_isInvalid(Cursor.kind))
188 return false;
189
190 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000191 const Decl *D = getCursorDecl(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000192 if (!D) {
193 assert(0 && "Invalid declaration cursor");
194 return true; // abort.
195 }
196
197 // Ignore implicit declarations, unless it's an objc method because
198 // currently we should report implicit methods for properties when indexing.
199 if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
200 return false;
201 }
202
203 // If we have a range of interest, and this cursor doesn't intersect with it,
204 // we're done.
205 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
206 SourceRange Range = getRawCursorExtent(Cursor);
207 if (Range.isInvalid() || CompareRegionOfInterest(Range))
208 return false;
209 }
210
211 switch (Visitor(Cursor, Parent, ClientData)) {
212 case CXChildVisit_Break:
213 return true;
214
215 case CXChildVisit_Continue:
216 return false;
217
218 case CXChildVisit_Recurse: {
219 bool ret = VisitChildren(Cursor);
220 if (PostChildrenVisitor)
221 if (PostChildrenVisitor(Cursor, ClientData))
222 return true;
223 return ret;
224 }
225 }
226
227 llvm_unreachable("Invalid CXChildVisitResult!");
228}
229
230static bool visitPreprocessedEntitiesInRange(SourceRange R,
231 PreprocessingRecord &PPRec,
232 CursorVisitor &Visitor) {
233 SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
234 FileID FID;
235
236 if (!Visitor.shouldVisitIncludedEntities()) {
237 // If the begin/end of the range lie in the same FileID, do the optimization
238 // where we skip preprocessed entities that do not come from the same FileID.
239 FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
240 if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
241 FID = FileID();
242 }
243
Benjamin Kramerb4ef6682015-02-06 17:25:10 +0000244 const auto &Entities = PPRec.getPreprocessedEntitiesInRange(R);
245 return Visitor.visitPreprocessedEntities(Entities.begin(), Entities.end(),
Guy Benyei11169dd2012-12-18 14:30:41 +0000246 PPRec, FID);
247}
248
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000249bool CursorVisitor::visitFileRegion() {
Guy Benyei11169dd2012-12-18 14:30:41 +0000250 if (RegionOfInterest.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000251 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000252
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000253 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000254 SourceManager &SM = Unit->getSourceManager();
255
256 std::pair<FileID, unsigned>
257 Begin = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getBegin())),
258 End = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getEnd()));
259
260 if (End.first != Begin.first) {
261 // If the end does not reside in the same file, try to recover by
262 // picking the end of the file of begin location.
263 End.first = Begin.first;
264 End.second = SM.getFileIDSize(Begin.first);
265 }
266
267 assert(Begin.first == End.first);
268 if (Begin.second > End.second)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000269 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000270
271 FileID File = Begin.first;
272 unsigned Offset = Begin.second;
273 unsigned Length = End.second - Begin.second;
274
275 if (!VisitDeclsOnly && !VisitPreprocessorLast)
276 if (visitPreprocessedEntitiesInRegion())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000277 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000278
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000279 if (visitDeclsFromFileRegion(File, Offset, Length))
280 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000281
282 if (!VisitDeclsOnly && VisitPreprocessorLast)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000283 return visitPreprocessedEntitiesInRegion();
284
285 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000286}
287
288static bool isInLexicalContext(Decl *D, DeclContext *DC) {
289 if (!DC)
290 return false;
291
292 for (DeclContext *DeclDC = D->getLexicalDeclContext();
293 DeclDC; DeclDC = DeclDC->getLexicalParent()) {
294 if (DeclDC == DC)
295 return true;
296 }
297 return false;
298}
299
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000300bool CursorVisitor::visitDeclsFromFileRegion(FileID File,
Guy Benyei11169dd2012-12-18 14:30:41 +0000301 unsigned Offset, unsigned Length) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000302 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000303 SourceManager &SM = Unit->getSourceManager();
304 SourceRange Range = RegionOfInterest;
305
306 SmallVector<Decl *, 16> Decls;
307 Unit->findFileRegionDecls(File, Offset, Length, Decls);
308
309 // If we didn't find any file level decls for the file, try looking at the
310 // file that it was included from.
311 while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
312 bool Invalid = false;
313 const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
314 if (Invalid)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000315 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000316
317 SourceLocation Outer;
318 if (SLEntry.isFile())
319 Outer = SLEntry.getFile().getIncludeLoc();
320 else
321 Outer = SLEntry.getExpansion().getExpansionLocStart();
322 if (Outer.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000323 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000324
Benjamin Kramer867ea1d2014-03-02 13:01:17 +0000325 std::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
Guy Benyei11169dd2012-12-18 14:30:41 +0000326 Length = 0;
327 Unit->findFileRegionDecls(File, Offset, Length, Decls);
328 }
329
330 assert(!Decls.empty());
331
332 bool VisitedAtLeastOnce = false;
Craig Topper69186e72014-06-08 08:38:04 +0000333 DeclContext *CurDC = nullptr;
Craig Topper2341c0d2013-07-04 03:08:24 +0000334 SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
335 for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000336 Decl *D = *DIt;
337 if (D->getSourceRange().isInvalid())
338 continue;
339
340 if (isInLexicalContext(D, CurDC))
341 continue;
342
343 CurDC = dyn_cast<DeclContext>(D);
344
345 if (TagDecl *TD = dyn_cast<TagDecl>(D))
346 if (!TD->isFreeStanding())
347 continue;
348
349 RangeComparisonResult CompRes = RangeCompare(SM, D->getSourceRange(),Range);
350 if (CompRes == RangeBefore)
351 continue;
352 if (CompRes == RangeAfter)
353 break;
354
355 assert(CompRes == RangeOverlap);
356 VisitedAtLeastOnce = true;
357
358 if (isa<ObjCContainerDecl>(D)) {
359 FileDI_current = &DIt;
360 FileDE_current = DE;
361 } else {
Craig Topper69186e72014-06-08 08:38:04 +0000362 FileDI_current = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +0000363 }
364
365 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000366 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000367 }
368
369 if (VisitedAtLeastOnce)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000370 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000371
372 // No Decls overlapped with the range. Move up the lexical context until there
373 // is a context that contains the range or we reach the translation unit
374 // level.
375 DeclContext *DC = DIt == Decls.begin() ? (*DIt)->getLexicalDeclContext()
376 : (*(DIt-1))->getLexicalDeclContext();
377
378 while (DC && !DC->isTranslationUnit()) {
379 Decl *D = cast<Decl>(DC);
380 SourceRange CurDeclRange = D->getSourceRange();
381 if (CurDeclRange.isInvalid())
382 break;
383
384 if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000385 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
386 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000387 }
388
389 DC = D->getLexicalDeclContext();
390 }
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000391
392 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000393}
394
395bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
396 if (!AU->getPreprocessor().getPreprocessingRecord())
397 return false;
398
399 PreprocessingRecord &PPRec
400 = *AU->getPreprocessor().getPreprocessingRecord();
401 SourceManager &SM = AU->getSourceManager();
402
403 if (RegionOfInterest.isValid()) {
404 SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
405 SourceLocation B = MappedRange.getBegin();
406 SourceLocation E = MappedRange.getEnd();
407
408 if (AU->isInPreambleFileID(B)) {
409 if (SM.isLoadedSourceLocation(E))
410 return visitPreprocessedEntitiesInRange(SourceRange(B, E),
411 PPRec, *this);
412
413 // Beginning of range lies in the preamble but it also extends beyond
414 // it into the main file. Split the range into 2 parts, one covering
415 // the preamble and another covering the main file. This allows subsequent
416 // calls to visitPreprocessedEntitiesInRange to accept a source range that
417 // lies in the same FileID, allowing it to skip preprocessed entities that
418 // do not come from the same FileID.
419 bool breaked =
420 visitPreprocessedEntitiesInRange(
421 SourceRange(B, AU->getEndOfPreambleFileID()),
422 PPRec, *this);
423 if (breaked) return true;
424 return visitPreprocessedEntitiesInRange(
425 SourceRange(AU->getStartOfMainFileID(), E),
426 PPRec, *this);
427 }
428
429 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
430 }
431
432 bool OnlyLocalDecls
433 = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
434
435 if (OnlyLocalDecls)
436 return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
437 PPRec);
438
439 return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
440}
441
442template<typename InputIterator>
443bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
444 InputIterator Last,
445 PreprocessingRecord &PPRec,
446 FileID FID) {
447 for (; First != Last; ++First) {
448 if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
449 continue;
450
451 PreprocessedEntity *PPE = *First;
Argyrios Kyrtzidis1030f262013-05-07 20:37:17 +0000452 if (!PPE)
453 continue;
454
Guy Benyei11169dd2012-12-18 14:30:41 +0000455 if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
456 if (Visit(MakeMacroExpansionCursor(ME, TU)))
457 return true;
Richard Smith66a81862015-05-04 02:25:31 +0000458
Guy Benyei11169dd2012-12-18 14:30:41 +0000459 continue;
460 }
Richard Smith66a81862015-05-04 02:25:31 +0000461
462 if (MacroDefinitionRecord *MD = dyn_cast<MacroDefinitionRecord>(PPE)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000463 if (Visit(MakeMacroDefinitionCursor(MD, TU)))
464 return true;
Richard Smith66a81862015-05-04 02:25:31 +0000465
Guy Benyei11169dd2012-12-18 14:30:41 +0000466 continue;
467 }
468
469 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
470 if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
471 return true;
472
473 continue;
474 }
475 }
476
477 return false;
478}
479
480/// \brief Visit the children of the given cursor.
481///
482/// \returns true if the visitation should be aborted, false if it
483/// should continue.
484bool CursorVisitor::VisitChildren(CXCursor Cursor) {
485 if (clang_isReference(Cursor.kind) &&
486 Cursor.kind != CXCursor_CXXBaseSpecifier) {
487 // By definition, references have no children.
488 return false;
489 }
490
491 // Set the Parent field to Cursor, then back to its old value once we're
492 // done.
493 SetParentRAII SetParent(Parent, StmtParent, Cursor);
494
495 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000496 Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +0000497 if (!D)
498 return false;
499
500 return VisitAttributes(D) || Visit(D);
501 }
502
503 if (clang_isStatement(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000504 if (const Stmt *S = getCursorStmt(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000505 return Visit(S);
506
507 return false;
508 }
509
510 if (clang_isExpression(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000511 if (const Expr *E = getCursorExpr(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000512 return Visit(E);
513
514 return false;
515 }
516
517 if (clang_isTranslationUnit(Cursor.kind)) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000518 CXTranslationUnit TU = getCursorTU(Cursor);
519 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000520
521 int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
522 for (unsigned I = 0; I != 2; ++I) {
523 if (VisitOrder[I]) {
524 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
525 RegionOfInterest.isInvalid()) {
526 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
527 TLEnd = CXXUnit->top_level_end();
528 TL != TLEnd; ++TL) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000529 if (Visit(MakeCXCursor(*TL, TU, RegionOfInterest), true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000530 return true;
531 }
532 } else if (VisitDeclContext(
533 CXXUnit->getASTContext().getTranslationUnitDecl()))
534 return true;
535 continue;
536 }
537
538 // Walk the preprocessing record.
539 if (CXXUnit->getPreprocessor().getPreprocessingRecord())
540 visitPreprocessedEntitiesInRegion();
541 }
542
543 return false;
544 }
545
546 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000547 if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000548 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
549 return Visit(BaseTSInfo->getTypeLoc());
550 }
551 }
552 }
553
554 if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +0000555 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +0000556 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
Richard Smithb1f9a282013-10-31 01:56:18 +0000557 if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())
Richard Smithb87c4652013-10-31 21:23:20 +0000558 return Visit(cxcursor::MakeCursorObjCClassRef(
559 ObjT->getInterface(),
560 A->getInterfaceLoc()->getTypeLoc().getLocStart(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +0000561 }
562
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000563 // If pointing inside a macro definition, check if the token is an identifier
564 // that was ever defined as a macro. In such a case, create a "pseudo" macro
565 // expansion cursor for that token.
566 SourceLocation BeginLoc = RegionOfInterest.getBegin();
567 if (Cursor.kind == CXCursor_MacroDefinition &&
568 BeginLoc == RegionOfInterest.getEnd()) {
569 SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000570 const MacroInfo *MI =
571 getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
Richard Smith66a81862015-05-04 02:25:31 +0000572 if (MacroDefinitionRecord *MacroDef =
573 checkForMacroInMacroDefinition(MI, Loc, TU))
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000574 return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
575 }
576
Guy Benyei11169dd2012-12-18 14:30:41 +0000577 // Nothing to visit at the moment.
578 return false;
579}
580
581bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
582 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
583 if (Visit(TSInfo->getTypeLoc()))
584 return true;
585
586 if (Stmt *Body = B->getBody())
587 return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
588
589 return false;
590}
591
Ted Kremenek03325582013-02-21 01:29:01 +0000592Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000593 if (RegionOfInterest.isValid()) {
594 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
595 if (Range.isInvalid())
David Blaikie7a30dc52013-02-21 01:47:18 +0000596 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000597
598 switch (CompareRegionOfInterest(Range)) {
599 case RangeBefore:
600 // This declaration comes before the region of interest; skip it.
David Blaikie7a30dc52013-02-21 01:47:18 +0000601 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000602
603 case RangeAfter:
604 // This declaration comes after the region of interest; we're done.
605 return false;
606
607 case RangeOverlap:
608 // This declaration overlaps the region of interest; visit it.
609 break;
610 }
611 }
612 return true;
613}
614
615bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
616 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
617
618 // FIXME: Eventually remove. This part of a hack to support proper
619 // iteration over all Decls contained lexically within an ObjC container.
620 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
621 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
622
623 for ( ; I != E; ++I) {
624 Decl *D = *I;
625 if (D->getLexicalDeclContext() != DC)
626 continue;
627 CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
628
629 // Ignore synthesized ivars here, otherwise if we have something like:
630 // @synthesize prop = _prop;
631 // and '_prop' is not declared, we will encounter a '_prop' ivar before
632 // encountering the 'prop' synthesize declaration and we will think that
633 // we passed the region-of-interest.
634 if (ObjCIvarDecl *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
635 if (ivarD->getSynthesize())
636 continue;
637 }
638
639 // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
640 // declarations is a mismatch with the compiler semantics.
641 if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
642 ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
643 if (!ID->isThisDeclarationADefinition())
644 Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
645
646 } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
647 ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
648 if (!PD->isThisDeclarationADefinition())
649 Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
650 }
651
Ted Kremenek03325582013-02-21 01:29:01 +0000652 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000653 if (!V.hasValue())
654 continue;
655 if (!V.getValue())
656 return false;
657 if (Visit(Cursor, true))
658 return true;
659 }
660 return false;
661}
662
663bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
664 llvm_unreachable("Translation units are visited directly by Visit()");
665}
666
Sergey Kalinichev8f3b1872015-11-15 13:48:32 +0000667bool CursorVisitor::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {
668 if (VisitTemplateParameters(D->getTemplateParameters()))
669 return true;
670
671 return Visit(MakeCXCursor(D->getTemplatedDecl(), TU, RegionOfInterest));
672}
673
Guy Benyei11169dd2012-12-18 14:30:41 +0000674bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
675 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
676 return Visit(TSInfo->getTypeLoc());
677
678 return false;
679}
680
681bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
682 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
683 return Visit(TSInfo->getTypeLoc());
684
685 return false;
686}
687
688bool CursorVisitor::VisitTagDecl(TagDecl *D) {
689 return VisitDeclContext(D);
690}
691
692bool CursorVisitor::VisitClassTemplateSpecializationDecl(
693 ClassTemplateSpecializationDecl *D) {
694 bool ShouldVisitBody = false;
695 switch (D->getSpecializationKind()) {
696 case TSK_Undeclared:
697 case TSK_ImplicitInstantiation:
698 // Nothing to visit
699 return false;
700
701 case TSK_ExplicitInstantiationDeclaration:
702 case TSK_ExplicitInstantiationDefinition:
703 break;
704
705 case TSK_ExplicitSpecialization:
706 ShouldVisitBody = true;
707 break;
708 }
709
710 // Visit the template arguments used in the specialization.
711 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
712 TypeLoc TL = SpecType->getTypeLoc();
David Blaikie6adc78e2013-02-18 22:06:02 +0000713 if (TemplateSpecializationTypeLoc TSTLoc =
714 TL.getAs<TemplateSpecializationTypeLoc>()) {
715 for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
716 if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000717 return true;
718 }
719 }
720
721 if (ShouldVisitBody && VisitCXXRecordDecl(D))
722 return true;
723
724 return false;
725}
726
727bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
728 ClassTemplatePartialSpecializationDecl *D) {
729 // FIXME: Visit the "outer" template parameter lists on the TagDecl
730 // before visiting these template parameters.
731 if (VisitTemplateParameters(D->getTemplateParameters()))
732 return true;
733
734 // Visit the partial specialization arguments.
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000735 const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
736 const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
737 for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
Guy Benyei11169dd2012-12-18 14:30:41 +0000738 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
739 return true;
740
741 return VisitCXXRecordDecl(D);
742}
743
744bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
745 // Visit the default argument.
746 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
747 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
748 if (Visit(DefArg->getTypeLoc()))
749 return true;
750
751 return false;
752}
753
754bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
755 if (Expr *Init = D->getInitExpr())
756 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
757 return false;
758}
759
760bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000761 unsigned NumParamList = DD->getNumTemplateParameterLists();
762 for (unsigned i = 0; i < NumParamList; i++) {
763 TemplateParameterList* Params = DD->getTemplateParameterList(i);
764 if (VisitTemplateParameters(Params))
765 return true;
766 }
767
Guy Benyei11169dd2012-12-18 14:30:41 +0000768 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
769 if (Visit(TSInfo->getTypeLoc()))
770 return true;
771
772 // Visit the nested-name-specifier, if present.
773 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
774 if (VisitNestedNameSpecifierLoc(QualifierLoc))
775 return true;
776
777 return false;
778}
779
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000780/// \brief Compare two base or member initializers based on their source order.
781static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
782 CXXCtorInitializer *const *Y) {
783 return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
784}
785
Guy Benyei11169dd2012-12-18 14:30:41 +0000786bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000787 unsigned NumParamList = ND->getNumTemplateParameterLists();
788 for (unsigned i = 0; i < NumParamList; i++) {
789 TemplateParameterList* Params = ND->getTemplateParameterList(i);
790 if (VisitTemplateParameters(Params))
791 return true;
792 }
793
Guy Benyei11169dd2012-12-18 14:30:41 +0000794 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
795 // Visit the function declaration's syntactic components in the order
796 // written. This requires a bit of work.
797 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
David Blaikie6adc78e2013-02-18 22:06:02 +0000798 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Guy Benyei11169dd2012-12-18 14:30:41 +0000799
800 // If we have a function declared directly (without the use of a typedef),
801 // visit just the return type. Otherwise, just visit the function's type
802 // now.
Alp Toker42a16a62014-01-25 23:51:36 +0000803 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getReturnLoc())) ||
Guy Benyei11169dd2012-12-18 14:30:41 +0000804 (!FTL && Visit(TL)))
805 return true;
806
807 // Visit the nested-name-specifier, if present.
808 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
809 if (VisitNestedNameSpecifierLoc(QualifierLoc))
810 return true;
811
812 // Visit the declaration name.
Argyrios Kyrtzidis4a4d2b42014-02-09 08:13:47 +0000813 if (!isa<CXXDestructorDecl>(ND))
814 if (VisitDeclarationNameInfo(ND->getNameInfo()))
815 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +0000816
817 // FIXME: Visit explicitly-specified template arguments!
818
819 // Visit the function parameters, if we have a function type.
David Blaikie6adc78e2013-02-18 22:06:02 +0000820 if (FTL && VisitFunctionTypeLoc(FTL, true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000821 return true;
822
Bill Wendling44426052012-12-20 19:22:21 +0000823 // FIXME: Attributes?
Guy Benyei11169dd2012-12-18 14:30:41 +0000824 }
825
826 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
827 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
828 // Find the initializers that were written in the source.
829 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
Aaron Ballman0ad78302014-03-13 17:34:31 +0000830 for (auto *I : Constructor->inits()) {
831 if (!I->isWritten())
Guy Benyei11169dd2012-12-18 14:30:41 +0000832 continue;
833
Aaron Ballman0ad78302014-03-13 17:34:31 +0000834 WrittenInits.push_back(I);
Guy Benyei11169dd2012-12-18 14:30:41 +0000835 }
836
837 // Sort the initializers in source order
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000838 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
839 &CompareCXXCtorInitializers);
840
Guy Benyei11169dd2012-12-18 14:30:41 +0000841 // Visit the initializers in source order
842 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
843 CXXCtorInitializer *Init = WrittenInits[I];
844 if (Init->isAnyMemberInitializer()) {
845 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
846 Init->getMemberLocation(), TU)))
847 return true;
848 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
849 if (Visit(TInfo->getTypeLoc()))
850 return true;
851 }
852
853 // Visit the initializer value.
854 if (Expr *Initializer = Init->getInit())
855 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
856 return true;
857 }
858 }
859
860 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
861 return true;
862 }
863
864 return false;
865}
866
867bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
868 if (VisitDeclaratorDecl(D))
869 return true;
870
871 if (Expr *BitWidth = D->getBitWidth())
872 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
873
874 return false;
875}
876
877bool CursorVisitor::VisitVarDecl(VarDecl *D) {
878 if (VisitDeclaratorDecl(D))
879 return true;
880
881 if (Expr *Init = D->getInit())
882 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
883
884 return false;
885}
886
887bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
888 if (VisitDeclaratorDecl(D))
889 return true;
890
891 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
892 if (Expr *DefArg = D->getDefaultArgument())
893 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
894
895 return false;
896}
897
898bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
899 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
900 // before visiting these template parameters.
901 if (VisitTemplateParameters(D->getTemplateParameters()))
902 return true;
903
904 return VisitFunctionDecl(D->getTemplatedDecl());
905}
906
907bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
908 // FIXME: Visit the "outer" template parameter lists on the TagDecl
909 // before visiting these template parameters.
910 if (VisitTemplateParameters(D->getTemplateParameters()))
911 return true;
912
913 return VisitCXXRecordDecl(D->getTemplatedDecl());
914}
915
916bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
917 if (VisitTemplateParameters(D->getTemplateParameters()))
918 return true;
919
920 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
921 VisitTemplateArgumentLoc(D->getDefaultArgument()))
922 return true;
923
924 return false;
925}
926
Douglas Gregor9bda6cf2015-07-07 03:58:14 +0000927bool CursorVisitor::VisitObjCTypeParamDecl(ObjCTypeParamDecl *D) {
928 // Visit the bound, if it's explicit.
929 if (D->hasExplicitBound()) {
930 if (auto TInfo = D->getTypeSourceInfo()) {
931 if (Visit(TInfo->getTypeLoc()))
932 return true;
933 }
934 }
935
936 return false;
937}
938
Guy Benyei11169dd2012-12-18 14:30:41 +0000939bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Alp Toker314cc812014-01-25 16:55:45 +0000940 if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
Guy Benyei11169dd2012-12-18 14:30:41 +0000941 if (Visit(TSInfo->getTypeLoc()))
942 return true;
943
Aaron Ballman43b68be2014-03-07 17:50:17 +0000944 for (const auto *P : ND->params()) {
945 if (Visit(MakeCXCursor(P, TU, RegionOfInterest)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000946 return true;
947 }
948
949 if (ND->isThisDeclarationADefinition() &&
950 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
951 return true;
952
953 return false;
954}
955
956template <typename DeclIt>
957static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
958 SourceManager &SM, SourceLocation EndLoc,
959 SmallVectorImpl<Decl *> &Decls) {
960 DeclIt next = *DI_current;
961 while (++next != DE_current) {
962 Decl *D_next = *next;
963 if (!D_next)
964 break;
965 SourceLocation L = D_next->getLocStart();
966 if (!L.isValid())
967 break;
968 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
969 *DI_current = next;
970 Decls.push_back(D_next);
971 continue;
972 }
973 break;
974 }
975}
976
Guy Benyei11169dd2012-12-18 14:30:41 +0000977bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
978 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
979 // an @implementation can lexically contain Decls that are not properly
980 // nested in the AST. When we identify such cases, we need to retrofit
981 // this nesting here.
982 if (!DI_current && !FileDI_current)
983 return VisitDeclContext(D);
984
985 // Scan the Decls that immediately come after the container
986 // in the current DeclContext. If any fall within the
987 // container's lexical region, stash them into a vector
988 // for later processing.
989 SmallVector<Decl *, 24> DeclsInContainer;
990 SourceLocation EndLoc = D->getSourceRange().getEnd();
991 SourceManager &SM = AU->getSourceManager();
992 if (EndLoc.isValid()) {
993 if (DI_current) {
994 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
995 DeclsInContainer);
996 } else {
997 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
998 DeclsInContainer);
999 }
1000 }
1001
1002 // The common case.
1003 if (DeclsInContainer.empty())
1004 return VisitDeclContext(D);
1005
1006 // Get all the Decls in the DeclContext, and sort them with the
1007 // additional ones we've collected. Then visit them.
Aaron Ballman629afae2014-03-07 19:56:05 +00001008 for (auto *SubDecl : D->decls()) {
1009 if (!SubDecl || SubDecl->getLexicalDeclContext() != D ||
1010 SubDecl->getLocStart().isInvalid())
Guy Benyei11169dd2012-12-18 14:30:41 +00001011 continue;
Aaron Ballman629afae2014-03-07 19:56:05 +00001012 DeclsInContainer.push_back(SubDecl);
Guy Benyei11169dd2012-12-18 14:30:41 +00001013 }
1014
1015 // Now sort the Decls so that they appear in lexical order.
1016 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
Benjamin Kramerbbdd7642014-03-01 14:48:57 +00001017 [&SM](Decl *A, Decl *B) {
1018 SourceLocation L_A = A->getLocStart();
1019 SourceLocation L_B = B->getLocStart();
1020 assert(L_A.isValid() && L_B.isValid());
1021 return SM.isBeforeInTranslationUnit(L_A, L_B);
1022 });
Guy Benyei11169dd2012-12-18 14:30:41 +00001023
1024 // Now visit the decls.
1025 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
1026 E = DeclsInContainer.end(); I != E; ++I) {
1027 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek03325582013-02-21 01:29:01 +00001028 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00001029 if (!V.hasValue())
1030 continue;
1031 if (!V.getValue())
1032 return false;
1033 if (Visit(Cursor, true))
1034 return true;
1035 }
1036 return false;
1037}
1038
1039bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1040 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1041 TU)))
1042 return true;
1043
Douglas Gregore9d95f12015-07-07 03:57:35 +00001044 if (VisitObjCTypeParamList(ND->getTypeParamList()))
1045 return true;
1046
Guy Benyei11169dd2012-12-18 14:30:41 +00001047 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1048 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1049 E = ND->protocol_end(); I != E; ++I, ++PL)
1050 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1051 return true;
1052
1053 return VisitObjCContainerDecl(ND);
1054}
1055
1056bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1057 if (!PID->isThisDeclarationADefinition())
1058 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1059
1060 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1061 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1062 E = PID->protocol_end(); I != E; ++I, ++PL)
1063 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1064 return true;
1065
1066 return VisitObjCContainerDecl(PID);
1067}
1068
1069bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1070 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1071 return true;
1072
1073 // FIXME: This implements a workaround with @property declarations also being
1074 // installed in the DeclContext for the @interface. Eventually this code
1075 // should be removed.
1076 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1077 if (!CDecl || !CDecl->IsClassExtension())
1078 return false;
1079
1080 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1081 if (!ID)
1082 return false;
1083
1084 IdentifierInfo *PropertyId = PD->getIdentifier();
1085 ObjCPropertyDecl *prevDecl =
1086 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1087
1088 if (!prevDecl)
1089 return false;
1090
1091 // Visit synthesized methods since they will be skipped when visiting
1092 // the @interface.
1093 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1094 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1095 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1096 return true;
1097
1098 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1099 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1100 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1101 return true;
1102
1103 return false;
1104}
1105
Douglas Gregore9d95f12015-07-07 03:57:35 +00001106bool CursorVisitor::VisitObjCTypeParamList(ObjCTypeParamList *typeParamList) {
1107 if (!typeParamList)
1108 return false;
1109
1110 for (auto *typeParam : *typeParamList) {
1111 // Visit the type parameter.
1112 if (Visit(MakeCXCursor(typeParam, TU, RegionOfInterest)))
1113 return true;
Douglas Gregore9d95f12015-07-07 03:57:35 +00001114 }
1115
1116 return false;
1117}
1118
Guy Benyei11169dd2012-12-18 14:30:41 +00001119bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1120 if (!D->isThisDeclarationADefinition()) {
1121 // Forward declaration is treated like a reference.
1122 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1123 }
1124
Douglas Gregore9d95f12015-07-07 03:57:35 +00001125 // Objective-C type parameters.
1126 if (VisitObjCTypeParamList(D->getTypeParamListAsWritten()))
1127 return true;
1128
Guy Benyei11169dd2012-12-18 14:30:41 +00001129 // Issue callbacks for super class.
1130 if (D->getSuperClass() &&
1131 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1132 D->getSuperClassLoc(),
1133 TU)))
1134 return true;
1135
Douglas Gregore9d95f12015-07-07 03:57:35 +00001136 if (TypeSourceInfo *SuperClassTInfo = D->getSuperClassTInfo())
1137 if (Visit(SuperClassTInfo->getTypeLoc()))
1138 return true;
1139
Guy Benyei11169dd2012-12-18 14:30:41 +00001140 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1141 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1142 E = D->protocol_end(); I != E; ++I, ++PL)
1143 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1144 return true;
1145
1146 return VisitObjCContainerDecl(D);
1147}
1148
1149bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1150 return VisitObjCContainerDecl(D);
1151}
1152
1153bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1154 // 'ID' could be null when dealing with invalid code.
1155 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1156 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1157 return true;
1158
1159 return VisitObjCImplDecl(D);
1160}
1161
1162bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1163#if 0
1164 // Issue callbacks for super class.
1165 // FIXME: No source location information!
1166 if (D->getSuperClass() &&
1167 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1168 D->getSuperClassLoc(),
1169 TU)))
1170 return true;
1171#endif
1172
1173 return VisitObjCImplDecl(D);
1174}
1175
1176bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1177 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1178 if (PD->isIvarNameSpecified())
1179 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1180
1181 return false;
1182}
1183
1184bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1185 return VisitDeclContext(D);
1186}
1187
1188bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1189 // Visit nested-name-specifier.
1190 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1191 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1192 return true;
1193
1194 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1195 D->getTargetNameLoc(), TU));
1196}
1197
1198bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1199 // Visit nested-name-specifier.
1200 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1201 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1202 return true;
1203 }
1204
1205 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1206 return true;
1207
1208 return VisitDeclarationNameInfo(D->getNameInfo());
1209}
1210
1211bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1212 // Visit nested-name-specifier.
1213 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1214 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1215 return true;
1216
1217 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1218 D->getIdentLocation(), TU));
1219}
1220
1221bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1222 // Visit nested-name-specifier.
1223 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1224 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1225 return true;
1226 }
1227
1228 return VisitDeclarationNameInfo(D->getNameInfo());
1229}
1230
1231bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1232 UnresolvedUsingTypenameDecl *D) {
1233 // Visit nested-name-specifier.
1234 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1235 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1236 return true;
1237
1238 return false;
1239}
1240
1241bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1242 switch (Name.getName().getNameKind()) {
1243 case clang::DeclarationName::Identifier:
1244 case clang::DeclarationName::CXXLiteralOperatorName:
1245 case clang::DeclarationName::CXXOperatorName:
1246 case clang::DeclarationName::CXXUsingDirective:
1247 return false;
1248
1249 case clang::DeclarationName::CXXConstructorName:
1250 case clang::DeclarationName::CXXDestructorName:
1251 case clang::DeclarationName::CXXConversionFunctionName:
1252 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1253 return Visit(TSInfo->getTypeLoc());
1254 return false;
1255
1256 case clang::DeclarationName::ObjCZeroArgSelector:
1257 case clang::DeclarationName::ObjCOneArgSelector:
1258 case clang::DeclarationName::ObjCMultiArgSelector:
1259 // FIXME: Per-identifier location info?
1260 return false;
1261 }
1262
1263 llvm_unreachable("Invalid DeclarationName::Kind!");
1264}
1265
1266bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1267 SourceRange Range) {
1268 // FIXME: This whole routine is a hack to work around the lack of proper
1269 // source information in nested-name-specifiers (PR5791). Since we do have
1270 // a beginning source location, we can visit the first component of the
1271 // nested-name-specifier, if it's a single-token component.
1272 if (!NNS)
1273 return false;
1274
1275 // Get the first component in the nested-name-specifier.
1276 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1277 NNS = Prefix;
1278
1279 switch (NNS->getKind()) {
1280 case NestedNameSpecifier::Namespace:
1281 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1282 TU));
1283
1284 case NestedNameSpecifier::NamespaceAlias:
1285 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1286 Range.getBegin(), TU));
1287
1288 case NestedNameSpecifier::TypeSpec: {
1289 // If the type has a form where we know that the beginning of the source
1290 // range matches up with a reference cursor. Visit the appropriate reference
1291 // cursor.
1292 const Type *T = NNS->getAsType();
1293 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1294 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1295 if (const TagType *Tag = dyn_cast<TagType>(T))
1296 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1297 if (const TemplateSpecializationType *TST
1298 = dyn_cast<TemplateSpecializationType>(T))
1299 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1300 break;
1301 }
1302
1303 case NestedNameSpecifier::TypeSpecWithTemplate:
1304 case NestedNameSpecifier::Global:
1305 case NestedNameSpecifier::Identifier:
Nikola Smiljanic67860242014-09-26 00:28:20 +00001306 case NestedNameSpecifier::Super:
Guy Benyei11169dd2012-12-18 14:30:41 +00001307 break;
1308 }
1309
1310 return false;
1311}
1312
1313bool
1314CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1315 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1316 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1317 Qualifiers.push_back(Qualifier);
1318
1319 while (!Qualifiers.empty()) {
1320 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1321 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1322 switch (NNS->getKind()) {
1323 case NestedNameSpecifier::Namespace:
1324 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1325 Q.getLocalBeginLoc(),
1326 TU)))
1327 return true;
1328
1329 break;
1330
1331 case NestedNameSpecifier::NamespaceAlias:
1332 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1333 Q.getLocalBeginLoc(),
1334 TU)))
1335 return true;
1336
1337 break;
1338
1339 case NestedNameSpecifier::TypeSpec:
1340 case NestedNameSpecifier::TypeSpecWithTemplate:
1341 if (Visit(Q.getTypeLoc()))
1342 return true;
1343
1344 break;
1345
1346 case NestedNameSpecifier::Global:
1347 case NestedNameSpecifier::Identifier:
Nikola Smiljanic67860242014-09-26 00:28:20 +00001348 case NestedNameSpecifier::Super:
Guy Benyei11169dd2012-12-18 14:30:41 +00001349 break;
1350 }
1351 }
1352
1353 return false;
1354}
1355
1356bool CursorVisitor::VisitTemplateParameters(
1357 const TemplateParameterList *Params) {
1358 if (!Params)
1359 return false;
1360
1361 for (TemplateParameterList::const_iterator P = Params->begin(),
1362 PEnd = Params->end();
1363 P != PEnd; ++P) {
1364 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1365 return true;
1366 }
1367
1368 return false;
1369}
1370
1371bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1372 switch (Name.getKind()) {
1373 case TemplateName::Template:
1374 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1375
1376 case TemplateName::OverloadedTemplate:
1377 // Visit the overloaded template set.
1378 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1379 return true;
1380
1381 return false;
1382
1383 case TemplateName::DependentTemplate:
1384 // FIXME: Visit nested-name-specifier.
1385 return false;
1386
1387 case TemplateName::QualifiedTemplate:
1388 // FIXME: Visit nested-name-specifier.
1389 return Visit(MakeCursorTemplateRef(
1390 Name.getAsQualifiedTemplateName()->getDecl(),
1391 Loc, TU));
1392
1393 case TemplateName::SubstTemplateTemplateParm:
1394 return Visit(MakeCursorTemplateRef(
1395 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1396 Loc, TU));
1397
1398 case TemplateName::SubstTemplateTemplateParmPack:
1399 return Visit(MakeCursorTemplateRef(
1400 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1401 Loc, TU));
1402 }
1403
1404 llvm_unreachable("Invalid TemplateName::Kind!");
1405}
1406
1407bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1408 switch (TAL.getArgument().getKind()) {
1409 case TemplateArgument::Null:
1410 case TemplateArgument::Integral:
1411 case TemplateArgument::Pack:
1412 return false;
1413
1414 case TemplateArgument::Type:
1415 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1416 return Visit(TSInfo->getTypeLoc());
1417 return false;
1418
1419 case TemplateArgument::Declaration:
1420 if (Expr *E = TAL.getSourceDeclExpression())
1421 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1422 return false;
1423
1424 case TemplateArgument::NullPtr:
1425 if (Expr *E = TAL.getSourceNullPtrExpression())
1426 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1427 return false;
1428
1429 case TemplateArgument::Expression:
1430 if (Expr *E = TAL.getSourceExpression())
1431 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1432 return false;
1433
1434 case TemplateArgument::Template:
1435 case TemplateArgument::TemplateExpansion:
1436 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1437 return true;
1438
1439 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1440 TAL.getTemplateNameLoc());
1441 }
1442
1443 llvm_unreachable("Invalid TemplateArgument::Kind!");
1444}
1445
1446bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1447 return VisitDeclContext(D);
1448}
1449
1450bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1451 return Visit(TL.getUnqualifiedLoc());
1452}
1453
1454bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1455 ASTContext &Context = AU->getASTContext();
1456
1457 // Some builtin types (such as Objective-C's "id", "sel", and
1458 // "Class") have associated declarations. Create cursors for those.
1459 QualType VisitType;
1460 switch (TL.getTypePtr()->getKind()) {
1461
1462 case BuiltinType::Void:
1463 case BuiltinType::NullPtr:
1464 case BuiltinType::Dependent:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001465 case BuiltinType::OCLImage1d:
1466 case BuiltinType::OCLImage1dArray:
1467 case BuiltinType::OCLImage1dBuffer:
1468 case BuiltinType::OCLImage2d:
1469 case BuiltinType::OCLImage2dArray:
Alexey Bader9c8453f2015-09-15 11:18:52 +00001470 case BuiltinType::OCLImage2dDepth:
1471 case BuiltinType::OCLImage2dArrayDepth:
1472 case BuiltinType::OCLImage2dMSAA:
1473 case BuiltinType::OCLImage2dArrayMSAA:
1474 case BuiltinType::OCLImage2dMSAADepth:
1475 case BuiltinType::OCLImage2dArrayMSAADepth:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001476 case BuiltinType::OCLImage3d:
NAKAMURA Takumi288c42e2013-02-07 12:47:42 +00001477 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +00001478 case BuiltinType::OCLEvent:
Alexey Bader9c8453f2015-09-15 11:18:52 +00001479 case BuiltinType::OCLClkEvent:
1480 case BuiltinType::OCLQueue:
1481 case BuiltinType::OCLNDRange:
1482 case BuiltinType::OCLReserveID:
Guy Benyei11169dd2012-12-18 14:30:41 +00001483#define BUILTIN_TYPE(Id, SingletonId)
1484#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1485#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1486#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1487#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1488#include "clang/AST/BuiltinTypes.def"
1489 break;
1490
1491 case BuiltinType::ObjCId:
1492 VisitType = Context.getObjCIdType();
1493 break;
1494
1495 case BuiltinType::ObjCClass:
1496 VisitType = Context.getObjCClassType();
1497 break;
1498
1499 case BuiltinType::ObjCSel:
1500 VisitType = Context.getObjCSelType();
1501 break;
1502 }
1503
1504 if (!VisitType.isNull()) {
1505 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1506 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1507 TU));
1508 }
1509
1510 return false;
1511}
1512
1513bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1514 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1515}
1516
1517bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1518 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1519}
1520
1521bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1522 if (TL.isDefinition())
1523 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1524
1525 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1526}
1527
1528bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1529 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1530}
1531
1532bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
Hans Wennborg59dbe862015-09-29 20:56:43 +00001533 return Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +00001534}
1535
1536bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1537 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1538 return true;
1539
Douglas Gregore9d95f12015-07-07 03:57:35 +00001540 for (unsigned I = 0, N = TL.getNumTypeArgs(); I != N; ++I) {
1541 if (Visit(TL.getTypeArgTInfo(I)->getTypeLoc()))
1542 return true;
1543 }
1544
Guy Benyei11169dd2012-12-18 14:30:41 +00001545 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1546 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1547 TU)))
1548 return true;
1549 }
1550
1551 return false;
1552}
1553
1554bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1555 return Visit(TL.getPointeeLoc());
1556}
1557
1558bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1559 return Visit(TL.getInnerLoc());
1560}
1561
1562bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1563 return Visit(TL.getPointeeLoc());
1564}
1565
1566bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1567 return Visit(TL.getPointeeLoc());
1568}
1569
1570bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1571 return Visit(TL.getPointeeLoc());
1572}
1573
1574bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1575 return Visit(TL.getPointeeLoc());
1576}
1577
1578bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1579 return Visit(TL.getPointeeLoc());
1580}
1581
1582bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1583 return Visit(TL.getModifiedLoc());
1584}
1585
1586bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1587 bool SkipResultType) {
Alp Toker42a16a62014-01-25 23:51:36 +00001588 if (!SkipResultType && Visit(TL.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001589 return true;
1590
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00001591 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1592 if (Decl *D = TL.getParam(I))
Guy Benyei11169dd2012-12-18 14:30:41 +00001593 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1594 return true;
1595
1596 return false;
1597}
1598
1599bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1600 if (Visit(TL.getElementLoc()))
1601 return true;
1602
1603 if (Expr *Size = TL.getSizeExpr())
1604 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1605
1606 return false;
1607}
1608
Reid Kleckner8a365022013-06-24 17:51:48 +00001609bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1610 return Visit(TL.getOriginalLoc());
1611}
1612
Reid Kleckner0503a872013-12-05 01:23:43 +00001613bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1614 return Visit(TL.getOriginalLoc());
1615}
1616
Guy Benyei11169dd2012-12-18 14:30:41 +00001617bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1618 TemplateSpecializationTypeLoc TL) {
1619 // Visit the template name.
1620 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1621 TL.getTemplateNameLoc()))
1622 return true;
1623
1624 // Visit the template arguments.
1625 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1626 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1627 return true;
1628
1629 return false;
1630}
1631
1632bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1633 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1634}
1635
1636bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1637 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1638 return Visit(TSInfo->getTypeLoc());
1639
1640 return false;
1641}
1642
1643bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1644 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1645 return Visit(TSInfo->getTypeLoc());
1646
1647 return false;
1648}
1649
1650bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
Hans Wennborg59dbe862015-09-29 20:56:43 +00001651 return VisitNestedNameSpecifierLoc(TL.getQualifierLoc());
Guy Benyei11169dd2012-12-18 14:30:41 +00001652}
1653
1654bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1655 DependentTemplateSpecializationTypeLoc TL) {
1656 // Visit the nested-name-specifier, if there is one.
1657 if (TL.getQualifierLoc() &&
1658 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1659 return true;
1660
1661 // Visit the template arguments.
1662 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1663 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1664 return true;
1665
1666 return false;
1667}
1668
1669bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1670 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1671 return true;
1672
1673 return Visit(TL.getNamedTypeLoc());
1674}
1675
1676bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1677 return Visit(TL.getPatternLoc());
1678}
1679
1680bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1681 if (Expr *E = TL.getUnderlyingExpr())
1682 return Visit(MakeCXCursor(E, StmtParent, TU));
1683
1684 return false;
1685}
1686
1687bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1688 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1689}
1690
1691bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1692 return Visit(TL.getValueLoc());
1693}
1694
1695#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1696bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1697 return Visit##PARENT##Loc(TL); \
1698}
1699
1700DEFAULT_TYPELOC_IMPL(Complex, Type)
1701DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1702DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1703DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1704DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1705DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1706DEFAULT_TYPELOC_IMPL(Vector, Type)
1707DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1708DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1709DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1710DEFAULT_TYPELOC_IMPL(Record, TagType)
1711DEFAULT_TYPELOC_IMPL(Enum, TagType)
1712DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1713DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1714DEFAULT_TYPELOC_IMPL(Auto, Type)
1715
1716bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1717 // Visit the nested-name-specifier, if present.
1718 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1719 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1720 return true;
1721
1722 if (D->isCompleteDefinition()) {
Aaron Ballman574705e2014-03-13 15:41:46 +00001723 for (const auto &I : D->bases()) {
1724 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001725 return true;
1726 }
1727 }
1728
1729 return VisitTagDecl(D);
1730}
1731
1732bool CursorVisitor::VisitAttributes(Decl *D) {
Aaron Ballmanb97112e2014-03-08 22:19:01 +00001733 for (const auto *I : D->attrs())
1734 if (Visit(MakeCXCursor(I, D, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001735 return true;
1736
1737 return false;
1738}
1739
1740//===----------------------------------------------------------------------===//
1741// Data-recursive visitor methods.
1742//===----------------------------------------------------------------------===//
1743
1744namespace {
1745#define DEF_JOB(NAME, DATA, KIND)\
1746class NAME : public VisitorJob {\
1747public:\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001748 NAME(const DATA *d, CXCursor parent) : \
1749 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei11169dd2012-12-18 14:30:41 +00001750 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001751 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei11169dd2012-12-18 14:30:41 +00001752};
1753
1754DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1755DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1756DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1757DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1758DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1759 ExplicitTemplateArgsVisitKind)
1760DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1761DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1762DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1763#undef DEF_JOB
1764
1765class DeclVisit : public VisitorJob {
1766public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001767 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei11169dd2012-12-18 14:30:41 +00001768 VisitorJob(parent, VisitorJob::DeclVisitKind,
Craig Topper69186e72014-06-08 08:38:04 +00001769 D, isFirst ? (void*) 1 : (void*) nullptr) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001770 static bool classof(const VisitorJob *VJ) {
1771 return VJ->getKind() == DeclVisitKind;
1772 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001773 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Dmitri Gribenkoe5423a72015-03-23 19:23:50 +00001774 bool isFirst() const { return data[1] != nullptr; }
Guy Benyei11169dd2012-12-18 14:30:41 +00001775};
1776class TypeLocVisit : public VisitorJob {
1777public:
1778 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1779 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1780 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1781
1782 static bool classof(const VisitorJob *VJ) {
1783 return VJ->getKind() == TypeLocVisitKind;
1784 }
1785
1786 TypeLoc get() const {
1787 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001788 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001789 }
1790};
1791
1792class LabelRefVisit : public VisitorJob {
1793public:
1794 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1795 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1796 labelLoc.getPtrEncoding()) {}
1797
1798 static bool classof(const VisitorJob *VJ) {
1799 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1800 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001801 const LabelDecl *get() const {
1802 return static_cast<const LabelDecl *>(data[0]);
1803 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001804 SourceLocation getLoc() const {
1805 return SourceLocation::getFromPtrEncoding(data[1]); }
1806};
1807
1808class NestedNameSpecifierLocVisit : public VisitorJob {
1809public:
1810 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1811 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1812 Qualifier.getNestedNameSpecifier(),
1813 Qualifier.getOpaqueData()) { }
1814
1815 static bool classof(const VisitorJob *VJ) {
1816 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1817 }
1818
1819 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001820 return NestedNameSpecifierLoc(
1821 const_cast<NestedNameSpecifier *>(
1822 static_cast<const NestedNameSpecifier *>(data[0])),
1823 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001824 }
1825};
1826
1827class DeclarationNameInfoVisit : public VisitorJob {
1828public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001829 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001830 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001831 static bool classof(const VisitorJob *VJ) {
1832 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1833 }
1834 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001835 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001836 switch (S->getStmtClass()) {
1837 default:
1838 llvm_unreachable("Unhandled Stmt");
1839 case clang::Stmt::MSDependentExistsStmtClass:
1840 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1841 case Stmt::CXXDependentScopeMemberExprClass:
1842 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1843 case Stmt::DependentScopeDeclRefExprClass:
1844 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001845 case Stmt::OMPCriticalDirectiveClass:
1846 return cast<OMPCriticalDirective>(S)->getDirectiveName();
Guy Benyei11169dd2012-12-18 14:30:41 +00001847 }
1848 }
1849};
1850class MemberRefVisit : public VisitorJob {
1851public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001852 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei11169dd2012-12-18 14:30:41 +00001853 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1854 L.getPtrEncoding()) {}
1855 static bool classof(const VisitorJob *VJ) {
1856 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1857 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001858 const FieldDecl *get() const {
1859 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001860 }
1861 SourceLocation getLoc() const {
1862 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1863 }
1864};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001865class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001866 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001867 VisitorWorkList &WL;
1868 CXCursor Parent;
1869public:
1870 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1871 : WL(wl), Parent(parent) {}
1872
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001873 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1874 void VisitBlockExpr(const BlockExpr *B);
1875 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1876 void VisitCompoundStmt(const CompoundStmt *S);
1877 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1878 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1879 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1880 void VisitCXXNewExpr(const CXXNewExpr *E);
1881 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1882 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1883 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1884 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1885 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1886 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1887 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1888 void VisitCXXCatchStmt(const CXXCatchStmt *S);
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00001889 void VisitCXXForRangeStmt(const CXXForRangeStmt *S);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001890 void VisitDeclRefExpr(const DeclRefExpr *D);
1891 void VisitDeclStmt(const DeclStmt *S);
1892 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1893 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1894 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1895 void VisitForStmt(const ForStmt *FS);
1896 void VisitGotoStmt(const GotoStmt *GS);
1897 void VisitIfStmt(const IfStmt *If);
1898 void VisitInitListExpr(const InitListExpr *IE);
1899 void VisitMemberExpr(const MemberExpr *M);
1900 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1901 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1902 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1903 void VisitOverloadExpr(const OverloadExpr *E);
1904 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1905 void VisitStmt(const Stmt *S);
1906 void VisitSwitchStmt(const SwitchStmt *S);
1907 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001908 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1909 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1910 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1911 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1912 void VisitVAArgExpr(const VAArgExpr *E);
1913 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1914 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1915 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1916 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001917 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
Alexander Musman3aaab662014-08-19 11:27:13 +00001918 void VisitOMPLoopDirective(const OMPLoopDirective *D);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001919 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00001920 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00001921 void VisitOMPForDirective(const OMPForDirective *D);
Alexander Musmanf82886e2014-09-18 05:12:34 +00001922 void VisitOMPForSimdDirective(const OMPForSimdDirective *D);
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00001923 void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
Alexey Bataev1e0498a2014-06-26 08:21:58 +00001924 void VisitOMPSectionDirective(const OMPSectionDirective *D);
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00001925 void VisitOMPSingleDirective(const OMPSingleDirective *D);
Alexander Musman80c22892014-07-17 08:54:58 +00001926 void VisitOMPMasterDirective(const OMPMasterDirective *D);
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001927 void VisitOMPCriticalDirective(const OMPCriticalDirective *D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00001928 void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
Alexander Musmane4e893b2014-09-23 09:33:00 +00001929 void VisitOMPParallelForSimdDirective(const OMPParallelForSimdDirective *D);
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00001930 void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective *D);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00001931 void VisitOMPTaskDirective(const OMPTaskDirective *D);
Alexey Bataev68446b72014-07-18 07:47:19 +00001932 void VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D);
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00001933 void VisitOMPBarrierDirective(const OMPBarrierDirective *D);
Alexey Bataev2df347a2014-07-18 10:17:07 +00001934 void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00001935 void VisitOMPTaskgroupDirective(const OMPTaskgroupDirective *D);
Alexey Bataev6d4ed052015-07-01 06:57:41 +00001936 void
1937 VisitOMPCancellationPointDirective(const OMPCancellationPointDirective *D);
Alexey Bataev80909872015-07-02 11:25:17 +00001938 void VisitOMPCancelDirective(const OMPCancelDirective *D);
Alexey Bataev6125da92014-07-21 11:26:11 +00001939 void VisitOMPFlushDirective(const OMPFlushDirective *D);
Alexey Bataev9fb6e642014-07-22 06:45:04 +00001940 void VisitOMPOrderedDirective(const OMPOrderedDirective *D);
Alexey Bataev0162e452014-07-22 10:10:35 +00001941 void VisitOMPAtomicDirective(const OMPAtomicDirective *D);
Alexey Bataev0bd520b2014-09-19 08:19:49 +00001942 void VisitOMPTargetDirective(const OMPTargetDirective *D);
Michael Wong65f367f2015-07-21 13:44:28 +00001943 void VisitOMPTargetDataDirective(const OMPTargetDataDirective *D);
Alexey Bataev13314bf2014-10-09 04:18:56 +00001944 void VisitOMPTeamsDirective(const OMPTeamsDirective *D);
Alexey Bataev49f6e782015-12-01 04:18:41 +00001945 void VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *D);
Alexey Bataev0a6ed842015-12-03 09:40:15 +00001946 void VisitOMPTaskLoopSimdDirective(const OMPTaskLoopSimdDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001947
Guy Benyei11169dd2012-12-18 14:30:41 +00001948private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001949 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001950 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1951 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001952 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1953 void AddStmt(const Stmt *S);
1954 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001955 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001956 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001957 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001958};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00001959} // end anonyous namespace
Guy Benyei11169dd2012-12-18 14:30:41 +00001960
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001961void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001962 // 'S' should always be non-null, since it comes from the
1963 // statement we are visiting.
1964 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1965}
1966
1967void
1968EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1969 if (Qualifier)
1970 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1971}
1972
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001973void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001974 if (S)
1975 WL.push_back(StmtVisit(S, Parent));
1976}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001977void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001978 if (D)
1979 WL.push_back(DeclVisit(D, Parent, isFirst));
1980}
1981void EnqueueVisitor::
1982 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1983 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001984 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001985}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001986void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001987 if (D)
1988 WL.push_back(MemberRefVisit(D, L, Parent));
1989}
1990void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1991 if (TI)
1992 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1993 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001994void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001995 unsigned size = WL.size();
Benjamin Kramer642f1732015-07-02 21:03:14 +00001996 for (const Stmt *SubStmt : S->children()) {
1997 AddStmt(SubStmt);
Guy Benyei11169dd2012-12-18 14:30:41 +00001998 }
1999 if (size == WL.size())
2000 return;
2001 // Now reverse the entries we just added. This will match the DFS
2002 // ordering performed by the worklist.
2003 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2004 std::reverse(I, E);
2005}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002006namespace {
2007class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
2008 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00002009 /// \brief Process clauses with list of variables.
2010 template <typename T>
2011 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002012public:
2013 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
2014#define OPENMP_CLAUSE(Name, Class) \
2015 void Visit##Class(const Class *C);
2016#include "clang/Basic/OpenMPKinds.def"
2017};
2018
Alexey Bataevaadd52e2014-02-13 05:29:23 +00002019void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
2020 Visitor->AddStmt(C->getCondition());
2021}
2022
Alexey Bataev3778b602014-07-17 07:32:53 +00002023void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
2024 Visitor->AddStmt(C->getCondition());
2025}
2026
Alexey Bataev568a8332014-03-06 06:15:19 +00002027void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
2028 Visitor->AddStmt(C->getNumThreads());
2029}
2030
Alexey Bataev62c87d22014-03-21 04:51:18 +00002031void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
2032 Visitor->AddStmt(C->getSafelen());
2033}
2034
Alexey Bataev66b15b52015-08-21 11:14:16 +00002035void OMPClauseEnqueue::VisitOMPSimdlenClause(const OMPSimdlenClause *C) {
2036 Visitor->AddStmt(C->getSimdlen());
2037}
2038
Alexander Musman8bd31e62014-05-27 15:12:19 +00002039void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
2040 Visitor->AddStmt(C->getNumForLoops());
2041}
2042
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002043void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00002044
Alexey Bataevbcbadb62014-05-06 06:04:14 +00002045void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
2046
Alexey Bataev56dafe82014-06-20 07:16:17 +00002047void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
2048 Visitor->AddStmt(C->getChunkSize());
Alexey Bataev040d5402015-05-12 08:35:28 +00002049 Visitor->AddStmt(C->getHelperChunkSize());
Alexey Bataev56dafe82014-06-20 07:16:17 +00002050}
2051
Alexey Bataev10e775f2015-07-30 11:36:16 +00002052void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *C) {
2053 Visitor->AddStmt(C->getNumForLoops());
2054}
Alexey Bataev142e1fc2014-06-20 09:44:06 +00002055
Alexey Bataev236070f2014-06-20 11:19:47 +00002056void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
2057
Alexey Bataev7aea99a2014-07-17 12:19:31 +00002058void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
2059
Alexey Bataev74ba3a52014-07-17 12:47:03 +00002060void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
2061
Alexey Bataevf98b00c2014-07-23 02:27:21 +00002062void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}
2063
Alexey Bataevdea47612014-07-23 07:46:59 +00002064void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {}
2065
Alexey Bataev67a4f222014-07-23 10:25:33 +00002066void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {}
2067
Alexey Bataev459dec02014-07-24 06:46:57 +00002068void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}
2069
Alexey Bataev82bad8b2014-07-24 08:55:34 +00002070void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
2071
Alexey Bataev346265e2015-09-25 10:37:12 +00002072void OMPClauseEnqueue::VisitOMPThreadsClause(const OMPThreadsClause *) {}
2073
Alexey Bataevd14d1e62015-09-28 06:39:35 +00002074void OMPClauseEnqueue::VisitOMPSIMDClause(const OMPSIMDClause *) {}
2075
Alexey Bataevb825de12015-12-07 10:51:44 +00002076void OMPClauseEnqueue::VisitOMPNogroupClause(const OMPNogroupClause *) {}
2077
Michael Wonge710d542015-08-07 16:16:36 +00002078void OMPClauseEnqueue::VisitOMPDeviceClause(const OMPDeviceClause *C) {
2079 Visitor->AddStmt(C->getDevice());
2080}
2081
Kelvin Li099bb8c2015-11-24 20:50:12 +00002082void OMPClauseEnqueue::VisitOMPNumTeamsClause(const OMPNumTeamsClause *C) {
2083 Visitor->AddStmt(C->getNumTeams());
2084}
2085
Kelvin Lia15fb1a2015-11-27 18:47:36 +00002086void OMPClauseEnqueue::VisitOMPThreadLimitClause(const OMPThreadLimitClause *C) {
2087 Visitor->AddStmt(C->getThreadLimit());
2088}
2089
Alexey Bataeva0569352015-12-01 10:17:31 +00002090void OMPClauseEnqueue::VisitOMPPriorityClause(const OMPPriorityClause *C) {
2091 Visitor->AddStmt(C->getPriority());
2092}
2093
Alexey Bataev1fd4aed2015-12-07 12:52:51 +00002094void OMPClauseEnqueue::VisitOMPGrainsizeClause(const OMPGrainsizeClause *C) {
2095 Visitor->AddStmt(C->getGrainsize());
2096}
2097
Alexey Bataev756c1962013-09-24 03:17:45 +00002098template<typename T>
2099void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Alexey Bataev03b340a2014-10-21 03:16:40 +00002100 for (const auto *I : Node->varlists()) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00002101 Visitor->AddStmt(I);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002102 }
Alexey Bataev756c1962013-09-24 03:17:45 +00002103}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002104
2105void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002106 VisitOMPClauseList(C);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002107 for (const auto *E : C->private_copies()) {
2108 Visitor->AddStmt(E);
2109 }
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002110}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002111void OMPClauseEnqueue::VisitOMPFirstprivateClause(
2112 const OMPFirstprivateClause *C) {
2113 VisitOMPClauseList(C);
2114}
Alexander Musman1bb328c2014-06-04 13:06:39 +00002115void OMPClauseEnqueue::VisitOMPLastprivateClause(
2116 const OMPLastprivateClause *C) {
2117 VisitOMPClauseList(C);
Alexey Bataev38e89532015-04-16 04:54:05 +00002118 for (auto *E : C->private_copies()) {
2119 Visitor->AddStmt(E);
2120 }
2121 for (auto *E : C->source_exprs()) {
2122 Visitor->AddStmt(E);
2123 }
2124 for (auto *E : C->destination_exprs()) {
2125 Visitor->AddStmt(E);
2126 }
2127 for (auto *E : C->assignment_ops()) {
2128 Visitor->AddStmt(E);
2129 }
Alexander Musman1bb328c2014-06-04 13:06:39 +00002130}
Alexey Bataev758e55e2013-09-06 18:03:48 +00002131void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002132 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00002133}
Alexey Bataevc5e02582014-06-16 07:08:35 +00002134void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
2135 VisitOMPClauseList(C);
Alexey Bataevf24e7b12015-10-08 09:10:53 +00002136 for (auto *E : C->privates()) {
2137 Visitor->AddStmt(E);
2138 }
Alexey Bataev794ba0d2015-04-10 10:43:45 +00002139 for (auto *E : C->lhs_exprs()) {
2140 Visitor->AddStmt(E);
2141 }
2142 for (auto *E : C->rhs_exprs()) {
2143 Visitor->AddStmt(E);
2144 }
2145 for (auto *E : C->reduction_ops()) {
2146 Visitor->AddStmt(E);
2147 }
Alexey Bataevc5e02582014-06-16 07:08:35 +00002148}
Alexander Musman8dba6642014-04-22 13:09:42 +00002149void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2150 VisitOMPClauseList(C);
Alexey Bataevbd9fec12015-08-18 06:47:21 +00002151 for (const auto *E : C->privates()) {
2152 Visitor->AddStmt(E);
2153 }
Alexander Musman3276a272015-03-21 10:12:56 +00002154 for (const auto *E : C->inits()) {
2155 Visitor->AddStmt(E);
2156 }
2157 for (const auto *E : C->updates()) {
2158 Visitor->AddStmt(E);
2159 }
2160 for (const auto *E : C->finals()) {
2161 Visitor->AddStmt(E);
2162 }
Alexander Musman8dba6642014-04-22 13:09:42 +00002163 Visitor->AddStmt(C->getStep());
Alexander Musman3276a272015-03-21 10:12:56 +00002164 Visitor->AddStmt(C->getCalcStep());
Alexander Musman8dba6642014-04-22 13:09:42 +00002165}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002166void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2167 VisitOMPClauseList(C);
2168 Visitor->AddStmt(C->getAlignment());
2169}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002170void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2171 VisitOMPClauseList(C);
Alexey Bataevf56f98c2015-04-16 05:39:01 +00002172 for (auto *E : C->source_exprs()) {
2173 Visitor->AddStmt(E);
2174 }
2175 for (auto *E : C->destination_exprs()) {
2176 Visitor->AddStmt(E);
2177 }
2178 for (auto *E : C->assignment_ops()) {
2179 Visitor->AddStmt(E);
2180 }
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002181}
Alexey Bataevbae9a792014-06-27 10:37:06 +00002182void
2183OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
2184 VisitOMPClauseList(C);
Alexey Bataeva63048e2015-03-23 06:18:07 +00002185 for (auto *E : C->source_exprs()) {
2186 Visitor->AddStmt(E);
2187 }
2188 for (auto *E : C->destination_exprs()) {
2189 Visitor->AddStmt(E);
2190 }
2191 for (auto *E : C->assignment_ops()) {
2192 Visitor->AddStmt(E);
2193 }
Alexey Bataevbae9a792014-06-27 10:37:06 +00002194}
Alexey Bataev6125da92014-07-21 11:26:11 +00002195void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2196 VisitOMPClauseList(C);
2197}
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +00002198void OMPClauseEnqueue::VisitOMPDependClause(const OMPDependClause *C) {
2199 VisitOMPClauseList(C);
2200}
Kelvin Li0bff7af2015-11-23 05:32:03 +00002201void OMPClauseEnqueue::VisitOMPMapClause(const OMPMapClause *C) {
2202 VisitOMPClauseList(C);
2203}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002204}
Alexey Bataev756c1962013-09-24 03:17:45 +00002205
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002206void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2207 unsigned size = WL.size();
2208 OMPClauseEnqueue Visitor(this);
2209 Visitor.Visit(S);
2210 if (size == WL.size())
2211 return;
2212 // Now reverse the entries we just added. This will match the DFS
2213 // ordering performed by the worklist.
2214 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2215 std::reverse(I, E);
2216}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002217void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002218 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2219}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002220void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002221 AddDecl(B->getBlockDecl());
2222}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002223void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002224 EnqueueChildren(E);
2225 AddTypeLoc(E->getTypeSourceInfo());
2226}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002227void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
Pete Cooper57d3f142015-07-30 17:22:52 +00002228 for (auto &I : llvm::reverse(S->body()))
2229 AddStmt(I);
Guy Benyei11169dd2012-12-18 14:30:41 +00002230}
2231void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002232VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002233 AddStmt(S->getSubStmt());
2234 AddDeclarationNameInfo(S);
2235 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2236 AddNestedNameSpecifierLoc(QualifierLoc);
2237}
2238
2239void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002240VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002241 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2242 AddDeclarationNameInfo(E);
2243 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2244 AddNestedNameSpecifierLoc(QualifierLoc);
2245 if (!E->isImplicitAccess())
2246 AddStmt(E->getBase());
2247}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002248void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002249 // Enqueue the initializer , if any.
2250 AddStmt(E->getInitializer());
2251 // Enqueue the array size, if any.
2252 AddStmt(E->getArraySize());
2253 // Enqueue the allocated type.
2254 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2255 // Enqueue the placement arguments.
2256 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2257 AddStmt(E->getPlacementArg(I-1));
2258}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002259void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002260 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2261 AddStmt(CE->getArg(I-1));
2262 AddStmt(CE->getCallee());
2263 AddStmt(CE->getArg(0));
2264}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002265void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2266 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002267 // Visit the name of the type being destroyed.
2268 AddTypeLoc(E->getDestroyedTypeInfo());
2269 // Visit the scope type that looks disturbingly like the nested-name-specifier
2270 // but isn't.
2271 AddTypeLoc(E->getScopeTypeInfo());
2272 // Visit the nested-name-specifier.
2273 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2274 AddNestedNameSpecifierLoc(QualifierLoc);
2275 // Visit base expression.
2276 AddStmt(E->getBase());
2277}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002278void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2279 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002280 AddTypeLoc(E->getTypeSourceInfo());
2281}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002282void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2283 const CXXTemporaryObjectExpr *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::VisitCXXTypeidExpr(const CXXTypeidExpr *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::VisitCXXUnresolvedConstructExpr(
2294 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002295 EnqueueChildren(E);
2296 AddTypeLoc(E->getTypeSourceInfo());
2297}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002298void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002299 EnqueueChildren(E);
2300 if (E->isTypeOperand())
2301 AddTypeLoc(E->getTypeOperandSourceInfo());
2302}
2303
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002304void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002305 EnqueueChildren(S);
2306 AddDecl(S->getExceptionDecl());
2307}
2308
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002309void EnqueueVisitor::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002310 AddStmt(S->getBody());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002311 AddStmt(S->getRangeInit());
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002312 AddDecl(S->getLoopVariable());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002313}
2314
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002315void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002316 if (DR->hasExplicitTemplateArgs()) {
2317 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2318 }
2319 WL.push_back(DeclRefExprParts(DR, Parent));
2320}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002321void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2322 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002323 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2324 AddDeclarationNameInfo(E);
2325 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2326}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002327void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002328 unsigned size = WL.size();
2329 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002330 for (const auto *D : S->decls()) {
2331 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002332 isFirst = false;
2333 }
2334 if (size == WL.size())
2335 return;
2336 // Now reverse the entries we just added. This will match the DFS
2337 // ordering performed by the worklist.
2338 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2339 std::reverse(I, E);
2340}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002341void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002342 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002343 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002344 D = E->designators_rbegin(), DEnd = E->designators_rend();
2345 D != DEnd; ++D) {
2346 if (D->isFieldDesignator()) {
2347 if (FieldDecl *Field = D->getField())
2348 AddMemberRef(Field, D->getFieldLoc());
2349 continue;
2350 }
2351 if (D->isArrayDesignator()) {
2352 AddStmt(E->getArrayIndex(*D));
2353 continue;
2354 }
2355 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2356 AddStmt(E->getArrayRangeEnd(*D));
2357 AddStmt(E->getArrayRangeStart(*D));
2358 }
2359}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002360void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002361 EnqueueChildren(E);
2362 AddTypeLoc(E->getTypeInfoAsWritten());
2363}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002364void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002365 AddStmt(FS->getBody());
2366 AddStmt(FS->getInc());
2367 AddStmt(FS->getCond());
2368 AddDecl(FS->getConditionVariable());
2369 AddStmt(FS->getInit());
2370}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002371void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002372 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2373}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002374void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002375 AddStmt(If->getElse());
2376 AddStmt(If->getThen());
2377 AddStmt(If->getCond());
2378 AddDecl(If->getConditionVariable());
2379}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002380void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002381 // We care about the syntactic form of the initializer list, only.
2382 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2383 IE = Syntactic;
2384 EnqueueChildren(IE);
2385}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002386void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002387 WL.push_back(MemberExprParts(M, Parent));
2388
2389 // If the base of the member access expression is an implicit 'this', don't
2390 // visit it.
2391 // FIXME: If we ever want to show these implicit accesses, this will be
2392 // unfortunate. However, clang_getCursor() relies on this behavior.
Argyrios Kyrtzidis58d0e7a2015-03-13 04:40:07 +00002393 if (M->isImplicitAccess())
2394 return;
2395
2396 // Ignore base anonymous struct/union fields, otherwise they will shadow the
2397 // real field that that we are interested in.
2398 if (auto *SubME = dyn_cast<MemberExpr>(M->getBase())) {
2399 if (auto *FD = dyn_cast_or_null<FieldDecl>(SubME->getMemberDecl())) {
2400 if (FD->isAnonymousStructOrUnion()) {
2401 AddStmt(SubME->getBase());
2402 return;
2403 }
2404 }
2405 }
2406
2407 AddStmt(M->getBase());
Guy Benyei11169dd2012-12-18 14:30:41 +00002408}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002409void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002410 AddTypeLoc(E->getEncodedTypeSourceInfo());
2411}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002412void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002413 EnqueueChildren(M);
2414 AddTypeLoc(M->getClassReceiverTypeInfo());
2415}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002416void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002417 // Visit the components of the offsetof expression.
2418 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2419 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2420 const OffsetOfNode &Node = E->getComponent(I-1);
2421 switch (Node.getKind()) {
2422 case OffsetOfNode::Array:
2423 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2424 break;
2425 case OffsetOfNode::Field:
2426 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2427 break;
2428 case OffsetOfNode::Identifier:
2429 case OffsetOfNode::Base:
2430 continue;
2431 }
2432 }
2433 // Visit the type into which we're computing the offset.
2434 AddTypeLoc(E->getTypeSourceInfo());
2435}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002436void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002437 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2438 WL.push_back(OverloadExprParts(E, Parent));
2439}
2440void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002441 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002442 EnqueueChildren(E);
2443 if (E->isArgumentType())
2444 AddTypeLoc(E->getArgumentTypeInfo());
2445}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002446void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002447 EnqueueChildren(S);
2448}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002449void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002450 AddStmt(S->getBody());
2451 AddStmt(S->getCond());
2452 AddDecl(S->getConditionVariable());
2453}
2454
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002455void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002456 AddStmt(W->getBody());
2457 AddStmt(W->getCond());
2458 AddDecl(W->getConditionVariable());
2459}
2460
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002461void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002462 for (unsigned I = E->getNumArgs(); I > 0; --I)
2463 AddTypeLoc(E->getArg(I-1));
2464}
2465
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002466void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002467 AddTypeLoc(E->getQueriedTypeSourceInfo());
2468}
2469
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002470void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002471 EnqueueChildren(E);
2472}
2473
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002474void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002475 VisitOverloadExpr(U);
2476 if (!U->isImplicitAccess())
2477 AddStmt(U->getBase());
2478}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002479void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002480 AddStmt(E->getSubExpr());
2481 AddTypeLoc(E->getWrittenTypeInfo());
2482}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002483void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002484 WL.push_back(SizeOfPackExprParts(E, Parent));
2485}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002486void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002487 // If the opaque value has a source expression, just transparently
2488 // visit that. This is useful for (e.g.) pseudo-object expressions.
2489 if (Expr *SourceExpr = E->getSourceExpr())
2490 return Visit(SourceExpr);
2491}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002492void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002493 AddStmt(E->getBody());
2494 WL.push_back(LambdaExprParts(E, Parent));
2495}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002496void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002497 // Treat the expression like its syntactic form.
2498 Visit(E->getSyntacticForm());
2499}
2500
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002501void EnqueueVisitor::VisitOMPExecutableDirective(
2502 const OMPExecutableDirective *D) {
2503 EnqueueChildren(D);
2504 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2505 E = D->clauses().end();
2506 I != E; ++I)
2507 EnqueueChildren(*I);
2508}
2509
Alexander Musman3aaab662014-08-19 11:27:13 +00002510void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
2511 VisitOMPExecutableDirective(D);
2512}
2513
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002514void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2515 VisitOMPExecutableDirective(D);
2516}
2517
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002518void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002519 VisitOMPLoopDirective(D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002520}
2521
Alexey Bataevf29276e2014-06-18 04:14:57 +00002522void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002523 VisitOMPLoopDirective(D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002524}
2525
Alexander Musmanf82886e2014-09-18 05:12:34 +00002526void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
2527 VisitOMPLoopDirective(D);
2528}
2529
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002530void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2531 VisitOMPExecutableDirective(D);
2532}
2533
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002534void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2535 VisitOMPExecutableDirective(D);
2536}
2537
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002538void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2539 VisitOMPExecutableDirective(D);
2540}
2541
Alexander Musman80c22892014-07-17 08:54:58 +00002542void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2543 VisitOMPExecutableDirective(D);
2544}
2545
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002546void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2547 VisitOMPExecutableDirective(D);
2548 AddDeclarationNameInfo(D);
2549}
2550
Alexey Bataev4acb8592014-07-07 13:01:15 +00002551void
2552EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002553 VisitOMPLoopDirective(D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002554}
2555
Alexander Musmane4e893b2014-09-23 09:33:00 +00002556void EnqueueVisitor::VisitOMPParallelForSimdDirective(
2557 const OMPParallelForSimdDirective *D) {
2558 VisitOMPLoopDirective(D);
2559}
2560
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002561void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2562 const OMPParallelSectionsDirective *D) {
2563 VisitOMPExecutableDirective(D);
2564}
2565
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002566void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2567 VisitOMPExecutableDirective(D);
2568}
2569
Alexey Bataev68446b72014-07-18 07:47:19 +00002570void
2571EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2572 VisitOMPExecutableDirective(D);
2573}
2574
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002575void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2576 VisitOMPExecutableDirective(D);
2577}
2578
Alexey Bataev2df347a2014-07-18 10:17:07 +00002579void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2580 VisitOMPExecutableDirective(D);
2581}
2582
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002583void EnqueueVisitor::VisitOMPTaskgroupDirective(
2584 const OMPTaskgroupDirective *D) {
2585 VisitOMPExecutableDirective(D);
2586}
2587
Alexey Bataev6125da92014-07-21 11:26:11 +00002588void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2589 VisitOMPExecutableDirective(D);
2590}
2591
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002592void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2593 VisitOMPExecutableDirective(D);
2594}
2595
Alexey Bataev0162e452014-07-22 10:10:35 +00002596void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2597 VisitOMPExecutableDirective(D);
2598}
2599
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002600void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
2601 VisitOMPExecutableDirective(D);
2602}
2603
Michael Wong65f367f2015-07-21 13:44:28 +00002604void EnqueueVisitor::VisitOMPTargetDataDirective(const
2605 OMPTargetDataDirective *D) {
2606 VisitOMPExecutableDirective(D);
2607}
2608
Alexey Bataev13314bf2014-10-09 04:18:56 +00002609void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {
2610 VisitOMPExecutableDirective(D);
2611}
2612
Alexey Bataev6d4ed052015-07-01 06:57:41 +00002613void EnqueueVisitor::VisitOMPCancellationPointDirective(
2614 const OMPCancellationPointDirective *D) {
2615 VisitOMPExecutableDirective(D);
2616}
2617
Alexey Bataev80909872015-07-02 11:25:17 +00002618void EnqueueVisitor::VisitOMPCancelDirective(const OMPCancelDirective *D) {
2619 VisitOMPExecutableDirective(D);
2620}
2621
Alexey Bataev49f6e782015-12-01 04:18:41 +00002622void EnqueueVisitor::VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *D) {
2623 VisitOMPLoopDirective(D);
2624}
2625
Alexey Bataev0a6ed842015-12-03 09:40:15 +00002626void EnqueueVisitor::VisitOMPTaskLoopSimdDirective(
2627 const OMPTaskLoopSimdDirective *D) {
2628 VisitOMPLoopDirective(D);
2629}
2630
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002631void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002632 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2633}
2634
2635bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2636 if (RegionOfInterest.isValid()) {
2637 SourceRange Range = getRawCursorExtent(C);
2638 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2639 return false;
2640 }
2641 return true;
2642}
2643
2644bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2645 while (!WL.empty()) {
2646 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002647 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002648
2649 // Set the Parent field, then back to its old value once we're done.
2650 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2651
2652 switch (LI.getKind()) {
2653 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002654 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002655 if (!D)
2656 continue;
2657
2658 // For now, perform default visitation for Decls.
2659 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2660 cast<DeclVisit>(&LI)->isFirst())))
2661 return true;
2662
2663 continue;
2664 }
2665 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2666 const ASTTemplateArgumentListInfo *ArgList =
2667 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2668 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2669 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2670 Arg != ArgEnd; ++Arg) {
2671 if (VisitTemplateArgumentLoc(*Arg))
2672 return true;
2673 }
2674 continue;
2675 }
2676 case VisitorJob::TypeLocVisitKind: {
2677 // Perform default visitation for TypeLocs.
2678 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2679 return true;
2680 continue;
2681 }
2682 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002683 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002684 if (LabelStmt *stmt = LS->getStmt()) {
2685 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2686 TU))) {
2687 return true;
2688 }
2689 }
2690 continue;
2691 }
2692
2693 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2694 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2695 if (VisitNestedNameSpecifierLoc(V->get()))
2696 return true;
2697 continue;
2698 }
2699
2700 case VisitorJob::DeclarationNameInfoVisitKind: {
2701 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2702 ->get()))
2703 return true;
2704 continue;
2705 }
2706 case VisitorJob::MemberRefVisitKind: {
2707 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2708 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2709 return true;
2710 continue;
2711 }
2712 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002713 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002714 if (!S)
2715 continue;
2716
2717 // Update the current cursor.
2718 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2719 if (!IsInRegionOfInterest(Cursor))
2720 continue;
2721 switch (Visitor(Cursor, Parent, ClientData)) {
2722 case CXChildVisit_Break: return true;
2723 case CXChildVisit_Continue: break;
2724 case CXChildVisit_Recurse:
2725 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002726 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002727 EnqueueWorkList(WL, S);
2728 break;
2729 }
2730 continue;
2731 }
2732 case VisitorJob::MemberExprPartsKind: {
2733 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002734 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002735
2736 // Visit the nested-name-specifier
2737 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2738 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2739 return true;
2740
2741 // Visit the declaration name.
2742 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2743 return true;
2744
2745 // Visit the explicitly-specified template arguments, if any.
2746 if (M->hasExplicitTemplateArgs()) {
2747 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2748 *ArgEnd = Arg + M->getNumTemplateArgs();
2749 Arg != ArgEnd; ++Arg) {
2750 if (VisitTemplateArgumentLoc(*Arg))
2751 return true;
2752 }
2753 }
2754 continue;
2755 }
2756 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002757 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002758 // Visit nested-name-specifier, if present.
2759 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2760 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2761 return true;
2762 // Visit declaration name.
2763 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2764 return true;
2765 continue;
2766 }
2767 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002768 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002769 // Visit the nested-name-specifier.
2770 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2771 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2772 return true;
2773 // Visit the declaration name.
2774 if (VisitDeclarationNameInfo(O->getNameInfo()))
2775 return true;
2776 // Visit the overloaded declaration reference.
2777 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2778 return true;
2779 continue;
2780 }
2781 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002782 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002783 NamedDecl *Pack = E->getPack();
2784 if (isa<TemplateTypeParmDecl>(Pack)) {
2785 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2786 E->getPackLoc(), TU)))
2787 return true;
2788
2789 continue;
2790 }
2791
2792 if (isa<TemplateTemplateParmDecl>(Pack)) {
2793 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2794 E->getPackLoc(), TU)))
2795 return true;
2796
2797 continue;
2798 }
2799
2800 // Non-type template parameter packs and function parameter packs are
2801 // treated like DeclRefExpr cursors.
2802 continue;
2803 }
2804
2805 case VisitorJob::LambdaExprPartsKind: {
2806 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002807 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002808 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2809 CEnd = E->explicit_capture_end();
2810 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002811 // FIXME: Lambda init-captures.
2812 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002813 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002814
Guy Benyei11169dd2012-12-18 14:30:41 +00002815 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2816 C->getLocation(),
2817 TU)))
2818 return true;
2819 }
2820
2821 // Visit parameters and return type, if present.
2822 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2823 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2824 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2825 // Visit the whole type.
2826 if (Visit(TL))
2827 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002828 } else if (FunctionProtoTypeLoc Proto =
2829 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002830 if (E->hasExplicitParameters()) {
2831 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002832 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2833 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002834 return true;
2835 } else {
2836 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002837 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002838 return true;
2839 }
2840 }
2841 }
2842 break;
2843 }
2844
2845 case VisitorJob::PostChildrenVisitKind:
2846 if (PostChildrenVisitor(Parent, ClientData))
2847 return true;
2848 break;
2849 }
2850 }
2851 return false;
2852}
2853
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002854bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002855 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002856 if (!WorkListFreeList.empty()) {
2857 WL = WorkListFreeList.back();
2858 WL->clear();
2859 WorkListFreeList.pop_back();
2860 }
2861 else {
2862 WL = new VisitorWorkList();
2863 WorkListCache.push_back(WL);
2864 }
2865 EnqueueWorkList(*WL, S);
2866 bool result = RunVisitorWorkList(*WL);
2867 WorkListFreeList.push_back(WL);
2868 return result;
2869}
2870
2871namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002872typedef SmallVector<SourceRange, 4> RefNamePieces;
Craig Topper69186e72014-06-08 08:38:04 +00002873RefNamePieces
2874buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
Craig Toppere335f252015-10-04 04:53:55 +00002875 const DeclarationNameInfo &NI, SourceRange QLoc,
Craig Topper69186e72014-06-08 08:38:04 +00002876 const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002877 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2878 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2879 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2880
2881 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2882
2883 RefNamePieces Pieces;
2884
2885 if (WantQualifier && QLoc.isValid())
2886 Pieces.push_back(QLoc);
2887
2888 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2889 Pieces.push_back(NI.getLoc());
2890
2891 if (WantTemplateArgs && TemplateArgs)
2892 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2893 TemplateArgs->RAngleLoc));
2894
2895 if (Kind == DeclarationName::CXXOperatorName) {
2896 Pieces.push_back(SourceLocation::getFromRawEncoding(
2897 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2898 Pieces.push_back(SourceLocation::getFromRawEncoding(
2899 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2900 }
2901
2902 if (WantSinglePiece) {
2903 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2904 Pieces.clear();
2905 Pieces.push_back(R);
2906 }
2907
2908 return Pieces;
2909}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002910}
Guy Benyei11169dd2012-12-18 14:30:41 +00002911
2912//===----------------------------------------------------------------------===//
2913// Misc. API hooks.
2914//===----------------------------------------------------------------------===//
2915
Chad Rosier05c71aa2013-03-27 18:28:23 +00002916static void fatal_error_handler(void *user_data, const std::string& reason,
2917 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002918 // Write the result out to stderr avoiding errs() because raw_ostreams can
2919 // call report_fatal_error.
2920 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2921 ::abort();
2922}
2923
Chandler Carruth66660742014-06-27 16:37:27 +00002924namespace {
2925struct RegisterFatalErrorHandler {
2926 RegisterFatalErrorHandler() {
2927 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2928 }
2929};
2930}
2931
2932static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
2933
Guy Benyei11169dd2012-12-18 14:30:41 +00002934extern "C" {
2935CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2936 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002937 // We use crash recovery to make some of our APIs more reliable, implicitly
2938 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002939 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2940 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002941
Chandler Carruth66660742014-06-27 16:37:27 +00002942 // Look through the managed static to trigger construction of the managed
2943 // static which registers our fatal error handler. This ensures it is only
2944 // registered once.
2945 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00002946
Adrian Prantlbc068582015-07-08 01:00:30 +00002947 // Initialize targets for clang module support.
2948 llvm::InitializeAllTargets();
2949 llvm::InitializeAllTargetMCs();
2950 llvm::InitializeAllAsmPrinters();
2951 llvm::InitializeAllAsmParsers();
2952
Adrian Prantlfb2398d2015-07-17 01:19:54 +00002953 CIndexer *CIdxr = new CIndexer();
2954
Guy Benyei11169dd2012-12-18 14:30:41 +00002955 if (excludeDeclarationsFromPCH)
2956 CIdxr->setOnlyLocalDecls();
2957 if (displayDiagnostics)
2958 CIdxr->setDisplayDiagnostics();
2959
2960 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2961 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2962 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2963 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2964 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2965 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2966
2967 return CIdxr;
2968}
2969
2970void clang_disposeIndex(CXIndex CIdx) {
2971 if (CIdx)
2972 delete static_cast<CIndexer *>(CIdx);
2973}
2974
2975void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2976 if (CIdx)
2977 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2978}
2979
2980unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2981 if (CIdx)
2982 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2983 return 0;
2984}
2985
2986void clang_toggleCrashRecovery(unsigned isEnabled) {
2987 if (isEnabled)
2988 llvm::CrashRecoveryContext::Enable();
2989 else
2990 llvm::CrashRecoveryContext::Disable();
2991}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002992
Guy Benyei11169dd2012-12-18 14:30:41 +00002993CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2994 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002995 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002996 enum CXErrorCode Result =
2997 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002998 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002999 assert((TU && Result == CXError_Success) ||
3000 (!TU && Result != CXError_Success));
3001 return TU;
3002}
3003
3004enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
3005 const char *ast_filename,
3006 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003007 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00003008 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003009
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003010 if (!CIdx || !ast_filename || !out_TU)
3011 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00003012
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00003013 LOG_FUNC_SECTION {
3014 *Log << ast_filename;
3015 }
3016
Guy Benyei11169dd2012-12-18 14:30:41 +00003017 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3018 FileSystemOptions FileSystemOpts;
3019
Justin Bognerd512c1e2014-10-15 00:33:06 +00003020 IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
3021 CompilerInstance::createDiagnostics(new DiagnosticOptions());
David Blaikie6f7382d2014-08-10 19:08:04 +00003022 std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
Adrian Prantlfb2398d2015-07-17 01:19:54 +00003023 ast_filename, CXXIdx->getPCHContainerOperations()->getRawReader(), Diags,
Adrian Prantl6b21ab22015-08-27 19:46:20 +00003024 FileSystemOpts, /*UseDebugInfo=*/false,
3025 CXXIdx->getOnlyLocalDecls(), None,
David Blaikie6f7382d2014-08-10 19:08:04 +00003026 /*CaptureDiagnostics=*/true,
3027 /*AllowPCHWithCompilerErrors=*/true,
3028 /*UserFilesAreVolatile=*/true);
3029 *out_TU = MakeCXTranslationUnit(CXXIdx, AU.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003030 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003031}
3032
3033unsigned clang_defaultEditingTranslationUnitOptions() {
3034 return CXTranslationUnit_PrecompiledPreamble |
3035 CXTranslationUnit_CacheCompletionResults;
3036}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003037
Guy Benyei11169dd2012-12-18 14:30:41 +00003038CXTranslationUnit
3039clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
3040 const char *source_filename,
3041 int num_command_line_args,
3042 const char * const *command_line_args,
3043 unsigned num_unsaved_files,
3044 struct CXUnsavedFile *unsaved_files) {
3045 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
3046 return clang_parseTranslationUnit(CIdx, source_filename,
3047 command_line_args, num_command_line_args,
3048 unsaved_files, num_unsaved_files,
3049 Options);
3050}
3051
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003052static CXErrorCode
3053clang_parseTranslationUnit_Impl(CXIndex CIdx, const char *source_filename,
3054 const char *const *command_line_args,
3055 int num_command_line_args,
3056 ArrayRef<CXUnsavedFile> unsaved_files,
3057 unsigned options, CXTranslationUnit *out_TU) {
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003058 // Set up the initial return values.
3059 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00003060 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003061
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003062 // Check arguments.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003063 if (!CIdx || !out_TU)
3064 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003065
Guy Benyei11169dd2012-12-18 14:30:41 +00003066 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3067
3068 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3069 setThreadBackgroundPriority();
3070
3071 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
3072 // FIXME: Add a flag for modules.
3073 TranslationUnitKind TUKind
3074 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00003075 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00003076 = options & CXTranslationUnit_CacheCompletionResults;
3077 bool IncludeBriefCommentsInCodeCompletion
3078 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
3079 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
3080 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
3081
3082 // Configure the diagnostics.
3083 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00003084 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00003085
3086 // Recover resources if we crash before exiting this function.
3087 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
3088 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00003089 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00003090
Ahmed Charlesb8984322014-03-07 20:03:18 +00003091 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3092 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003093
3094 // Recover resources if we crash before exiting this function.
3095 llvm::CrashRecoveryContextCleanupRegistrar<
3096 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3097
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003098 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003099 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003100 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003101 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003102 }
3103
Ahmed Charlesb8984322014-03-07 20:03:18 +00003104 std::unique_ptr<std::vector<const char *>> Args(
3105 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003106
3107 // Recover resources if we crash before exiting this method.
3108 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
3109 ArgsCleanup(Args.get());
3110
3111 // Since the Clang C library is primarily used by batch tools dealing with
3112 // (often very broken) source code, where spell-checking can have a
3113 // significant negative impact on performance (particularly when
3114 // precompiled headers are involved), we disable it by default.
3115 // Only do this if we haven't found a spell-checking-related argument.
3116 bool FoundSpellCheckingArgument = false;
3117 for (int I = 0; I != num_command_line_args; ++I) {
3118 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
3119 strcmp(command_line_args[I], "-fspell-checking") == 0) {
3120 FoundSpellCheckingArgument = true;
3121 break;
3122 }
3123 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003124 Args->insert(Args->end(), command_line_args,
3125 command_line_args + num_command_line_args);
3126
Benjamin Kramerc02670e2015-11-18 16:14:27 +00003127 if (!FoundSpellCheckingArgument)
3128 Args->insert(Args->begin() + 1, "-fno-spell-checking");
3129
Guy Benyei11169dd2012-12-18 14:30:41 +00003130 // The 'source_filename' argument is optional. If the caller does not
3131 // specify it then it is assumed that the source file is specified
3132 // in the actual argument list.
3133 // Put the source file after command_line_args otherwise if '-x' flag is
3134 // present it will be unused.
3135 if (source_filename)
3136 Args->push_back(source_filename);
3137
3138 // Do we need the detailed preprocessing record?
3139 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
3140 Args->push_back("-Xclang");
3141 Args->push_back("-detailed-preprocessing-record");
3142 }
3143
3144 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00003145 std::unique_ptr<ASTUnit> ErrUnit;
3146 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003147 Args->data(), Args->data() + Args->size(),
3148 CXXIdx->getPCHContainerOperations(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00003149 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
3150 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
3151 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
3152 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
3153 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
Argyrios Kyrtzidisa3e2ff12015-11-20 03:36:21 +00003154 /*UserFilesAreVolatile=*/true, ForSerialization,
3155 CXXIdx->getPCHContainerOperations()->getRawReader().getFormat(),
3156 &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00003157
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003158 // Early failures in LoadFromCommandLine may return with ErrUnit unset.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003159 if (!Unit && !ErrUnit)
3160 return CXError_ASTReadError;
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003161
Guy Benyei11169dd2012-12-18 14:30:41 +00003162 if (NumErrors != Diags->getClient()->getNumErrors()) {
3163 // Make sure to check that 'Unit' is non-NULL.
3164 if (CXXIdx->getDisplayDiagnostics())
3165 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
3166 }
3167
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003168 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get()))
3169 return CXError_ASTReadError;
3170
3171 *out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
3172 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003173}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003174
3175CXTranslationUnit
3176clang_parseTranslationUnit(CXIndex CIdx,
3177 const char *source_filename,
3178 const char *const *command_line_args,
3179 int num_command_line_args,
3180 struct CXUnsavedFile *unsaved_files,
3181 unsigned num_unsaved_files,
3182 unsigned options) {
3183 CXTranslationUnit TU;
3184 enum CXErrorCode Result = clang_parseTranslationUnit2(
3185 CIdx, source_filename, command_line_args, num_command_line_args,
3186 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00003187 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003188 assert((TU && Result == CXError_Success) ||
3189 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003190 return TU;
3191}
3192
3193enum CXErrorCode clang_parseTranslationUnit2(
Benjamin Kramerc02670e2015-11-18 16:14:27 +00003194 CXIndex CIdx, const char *source_filename,
3195 const char *const *command_line_args, int num_command_line_args,
3196 struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
3197 unsigned options, CXTranslationUnit *out_TU) {
3198 SmallVector<const char *, 4> Args;
3199 Args.push_back("clang");
3200 Args.append(command_line_args, command_line_args + num_command_line_args);
3201 return clang_parseTranslationUnit2FullArgv(
3202 CIdx, source_filename, Args.data(), Args.size(), unsaved_files,
3203 num_unsaved_files, options, out_TU);
3204}
3205
3206enum CXErrorCode clang_parseTranslationUnit2FullArgv(
3207 CXIndex CIdx, const char *source_filename,
3208 const char *const *command_line_args, int num_command_line_args,
3209 struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
3210 unsigned options, CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003211 LOG_FUNC_SECTION {
3212 *Log << source_filename << ": ";
3213 for (int i = 0; i != num_command_line_args; ++i)
3214 *Log << command_line_args[i] << " ";
3215 }
3216
Alp Toker9d85b182014-07-07 01:23:14 +00003217 if (num_unsaved_files && !unsaved_files)
3218 return CXError_InvalidArguments;
3219
Alp Toker5c532982014-07-07 22:42:03 +00003220 CXErrorCode result = CXError_Failure;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003221 auto ParseTranslationUnitImpl = [=, &result] {
3222 result = clang_parseTranslationUnit_Impl(
3223 CIdx, source_filename, command_line_args, num_command_line_args,
3224 llvm::makeArrayRef(unsaved_files, num_unsaved_files), options, out_TU);
3225 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003226 llvm::CrashRecoveryContext CRC;
3227
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003228 if (!RunSafely(CRC, ParseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003229 fprintf(stderr, "libclang: crash detected during parsing: {\n");
3230 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3231 fprintf(stderr, " 'command_line_args' : [");
3232 for (int i = 0; i != num_command_line_args; ++i) {
3233 if (i)
3234 fprintf(stderr, ", ");
3235 fprintf(stderr, "'%s'", command_line_args[i]);
3236 }
3237 fprintf(stderr, "],\n");
3238 fprintf(stderr, " 'unsaved_files' : [");
3239 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3240 if (i)
3241 fprintf(stderr, ", ");
3242 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3243 unsaved_files[i].Length);
3244 }
3245 fprintf(stderr, "],\n");
3246 fprintf(stderr, " 'options' : %d,\n", options);
3247 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003248
3249 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003250 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003251 if (CXTranslationUnit *TU = out_TU)
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003252 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003253 }
Alp Toker5c532982014-07-07 22:42:03 +00003254
3255 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003256}
3257
3258unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
3259 return CXSaveTranslationUnit_None;
3260}
3261
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003262static CXSaveError clang_saveTranslationUnit_Impl(CXTranslationUnit TU,
3263 const char *FileName,
3264 unsigned options) {
3265 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003266 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3267 setThreadBackgroundPriority();
3268
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003269 bool hadError = cxtu::getASTUnit(TU)->Save(FileName);
3270 return hadError ? CXSaveError_Unknown : CXSaveError_None;
Guy Benyei11169dd2012-12-18 14:30:41 +00003271}
3272
3273int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3274 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003275 LOG_FUNC_SECTION {
3276 *Log << TU << ' ' << FileName;
3277 }
3278
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003279 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003280 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003281 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003282 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003283
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003284 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003285 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3286 if (!CXXUnit->hasSema())
3287 return CXSaveError_InvalidTU;
3288
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003289 CXSaveError result;
3290 auto SaveTranslationUnitImpl = [=, &result]() {
3291 result = clang_saveTranslationUnit_Impl(TU, FileName, options);
3292 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003293
3294 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3295 getenv("LIBCLANG_NOTHREADS")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003296 SaveTranslationUnitImpl();
Guy Benyei11169dd2012-12-18 14:30:41 +00003297
3298 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3299 PrintLibclangResourceUsage(TU);
3300
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003301 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003302 }
3303
3304 // We have an AST that has invalid nodes due to compiler errors.
3305 // Use a crash recovery thread for protection.
3306
3307 llvm::CrashRecoveryContext CRC;
3308
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003309 if (!RunSafely(CRC, SaveTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003310 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3311 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3312 fprintf(stderr, " 'options' : %d,\n", options);
3313 fprintf(stderr, "}\n");
3314
3315 return CXSaveError_Unknown;
3316
3317 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3318 PrintLibclangResourceUsage(TU);
3319 }
3320
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003321 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003322}
3323
3324void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3325 if (CTUnit) {
3326 // If the translation unit has been marked as unsafe to free, just discard
3327 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003328 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3329 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003330 return;
3331
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003332 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003333 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003334 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3335 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003336 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003337 delete CTUnit;
3338 }
3339}
3340
3341unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3342 return CXReparse_None;
3343}
3344
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003345static CXErrorCode
3346clang_reparseTranslationUnit_Impl(CXTranslationUnit TU,
3347 ArrayRef<CXUnsavedFile> unsaved_files,
3348 unsigned options) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003349 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003350 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003351 LOG_BAD_TU(TU);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003352 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003353 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003354
3355 // Reset the associated diagnostics.
3356 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003357 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003358
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003359 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003360 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3361 setThreadBackgroundPriority();
3362
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003363 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003364 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003365
3366 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3367 new std::vector<ASTUnit::RemappedFile>());
3368
Guy Benyei11169dd2012-12-18 14:30:41 +00003369 // Recover resources if we crash before exiting this function.
3370 llvm::CrashRecoveryContextCleanupRegistrar<
3371 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003372
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003373 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003374 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003375 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003376 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003377 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003378
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003379 if (!CXXUnit->Reparse(CXXIdx->getPCHContainerOperations(),
3380 *RemappedFiles.get()))
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003381 return CXError_Success;
3382 if (isASTReadError(CXXUnit))
3383 return CXError_ASTReadError;
3384 return CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003385}
3386
3387int clang_reparseTranslationUnit(CXTranslationUnit TU,
3388 unsigned num_unsaved_files,
3389 struct CXUnsavedFile *unsaved_files,
3390 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003391 LOG_FUNC_SECTION {
3392 *Log << TU;
3393 }
3394
Alp Toker9d85b182014-07-07 01:23:14 +00003395 if (num_unsaved_files && !unsaved_files)
3396 return CXError_InvalidArguments;
3397
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003398 CXErrorCode result;
3399 auto ReparseTranslationUnitImpl = [=, &result]() {
3400 result = clang_reparseTranslationUnit_Impl(
3401 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options);
3402 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003403
3404 if (getenv("LIBCLANG_NOTHREADS")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003405 ReparseTranslationUnitImpl();
Alp Toker5c532982014-07-07 22:42:03 +00003406 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003407 }
3408
3409 llvm::CrashRecoveryContext CRC;
3410
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003411 if (!RunSafely(CRC, ReparseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003412 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003413 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003414 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003415 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3416 PrintLibclangResourceUsage(TU);
3417
Alp Toker5c532982014-07-07 22:42:03 +00003418 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003419}
3420
3421
3422CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003423 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003424 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003425 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003426 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003427
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003428 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003429 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003430}
3431
3432CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003433 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003434 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003435 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003436 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003437
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003438 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003439 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3440}
3441
3442} // end: extern "C"
3443
3444//===----------------------------------------------------------------------===//
3445// CXFile Operations.
3446//===----------------------------------------------------------------------===//
3447
3448extern "C" {
3449CXString clang_getFileName(CXFile SFile) {
3450 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003451 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003452
3453 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003454 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003455}
3456
3457time_t clang_getFileTime(CXFile SFile) {
3458 if (!SFile)
3459 return 0;
3460
3461 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3462 return FEnt->getModificationTime();
3463}
3464
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003465CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003466 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003467 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003468 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003469 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003470
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003471 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003472
3473 FileManager &FMgr = CXXUnit->getFileManager();
3474 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3475}
3476
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003477unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3478 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003479 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003480 LOG_BAD_TU(TU);
3481 return 0;
3482 }
3483
3484 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003485 return 0;
3486
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003487 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003488 FileEntry *FEnt = static_cast<FileEntry *>(file);
3489 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3490 .isFileMultipleIncludeGuarded(FEnt);
3491}
3492
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003493int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3494 if (!file || !outID)
3495 return 1;
3496
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003497 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003498 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3499 outID->data[0] = ID.getDevice();
3500 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003501 outID->data[2] = FEnt->getModificationTime();
3502 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003503}
3504
Argyrios Kyrtzidisac3997e2014-08-16 00:26:19 +00003505int clang_File_isEqual(CXFile file1, CXFile file2) {
3506 if (file1 == file2)
3507 return true;
3508
3509 if (!file1 || !file2)
3510 return false;
3511
3512 FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
3513 FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
3514 return FEnt1->getUniqueID() == FEnt2->getUniqueID();
3515}
3516
Guy Benyei11169dd2012-12-18 14:30:41 +00003517} // end: extern "C"
3518
3519//===----------------------------------------------------------------------===//
3520// CXCursor Operations.
3521//===----------------------------------------------------------------------===//
3522
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003523static const Decl *getDeclFromExpr(const Stmt *E) {
3524 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003525 return getDeclFromExpr(CE->getSubExpr());
3526
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003527 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003528 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003529 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003530 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003531 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003532 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003533 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003534 if (PRE->isExplicitProperty())
3535 return PRE->getExplicitProperty();
3536 // It could be messaging both getter and setter as in:
3537 // ++myobj.myprop;
3538 // in which case prefer to associate the setter since it is less obvious
3539 // from inspecting the source that the setter is going to get called.
3540 if (PRE->isMessagingSetter())
3541 return PRE->getImplicitPropertySetter();
3542 return PRE->getImplicitPropertyGetter();
3543 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003544 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003545 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003546 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003547 if (Expr *Src = OVE->getSourceExpr())
3548 return getDeclFromExpr(Src);
3549
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003550 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003551 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003552 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003553 if (!CE->isElidable())
3554 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003555 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003556 return OME->getMethodDecl();
3557
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003558 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003559 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003560 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003561 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3562 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003563 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003564 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3565 isa<ParmVarDecl>(SizeOfPack->getPack()))
3566 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003567
3568 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003569}
3570
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003571static SourceLocation getLocationFromExpr(const Expr *E) {
3572 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003573 return getLocationFromExpr(CE->getSubExpr());
3574
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003575 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003576 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003577 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003578 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003579 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003580 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003581 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003582 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003583 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003584 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003585 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003586 return PropRef->getLocation();
3587
3588 return E->getLocStart();
3589}
3590
Aaron Ballmana85d3f82015-11-12 15:25:06 +00003591static std::string getMangledStructor(std::unique_ptr<MangleContext> &M,
3592 std::unique_ptr<llvm::DataLayout> &DL,
3593 const NamedDecl *ND,
3594 unsigned StructorType) {
3595 std::string FrontendBuf;
3596 llvm::raw_string_ostream FOS(FrontendBuf);
3597
3598 if (const auto *CD = dyn_cast_or_null<CXXConstructorDecl>(ND))
3599 M->mangleCXXCtor(CD, static_cast<CXXCtorType>(StructorType), FOS);
3600 else if (const auto *DD = dyn_cast_or_null<CXXDestructorDecl>(ND))
3601 M->mangleCXXDtor(DD, static_cast<CXXDtorType>(StructorType), FOS);
3602
3603 std::string BackendBuf;
3604 llvm::raw_string_ostream BOS(BackendBuf);
3605
3606 llvm::Mangler::getNameWithPrefix(BOS, llvm::Twine(FOS.str()), *DL);
3607
3608 return BOS.str();
3609}
3610
Guy Benyei11169dd2012-12-18 14:30:41 +00003611extern "C" {
3612
3613unsigned clang_visitChildren(CXCursor parent,
3614 CXCursorVisitor visitor,
3615 CXClientData client_data) {
3616 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3617 /*VisitPreprocessorLast=*/false);
3618 return CursorVis.VisitChildren(parent);
3619}
3620
3621#ifndef __has_feature
3622#define __has_feature(x) 0
3623#endif
3624#if __has_feature(blocks)
3625typedef enum CXChildVisitResult
3626 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3627
3628static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3629 CXClientData client_data) {
3630 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3631 return block(cursor, parent);
3632}
3633#else
3634// If we are compiled with a compiler that doesn't have native blocks support,
3635// define and call the block manually, so the
3636typedef struct _CXChildVisitResult
3637{
3638 void *isa;
3639 int flags;
3640 int reserved;
3641 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3642 CXCursor);
3643} *CXCursorVisitorBlock;
3644
3645static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3646 CXClientData client_data) {
3647 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3648 return block->invoke(block, cursor, parent);
3649}
3650#endif
3651
3652
3653unsigned clang_visitChildrenWithBlock(CXCursor parent,
3654 CXCursorVisitorBlock block) {
3655 return clang_visitChildren(parent, visitWithBlock, block);
3656}
3657
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003658static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003659 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003660 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003661
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003662 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003663 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003664 if (const ObjCPropertyImplDecl *PropImpl =
3665 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003666 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003667 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003668
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003669 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003670 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003671 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003672
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003673 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003674 }
3675
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003676 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003677 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003678
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003679 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003680 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3681 // and returns different names. NamedDecl returns the class name and
3682 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003683 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003684
3685 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003686 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003687
3688 SmallString<1024> S;
3689 llvm::raw_svector_ostream os(S);
3690 ND->printName(os);
3691
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003692 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003693}
3694
3695CXString clang_getCursorSpelling(CXCursor C) {
3696 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003697 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003698
3699 if (clang_isReference(C.kind)) {
3700 switch (C.kind) {
3701 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003702 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003703 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003704 }
3705 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003706 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003707 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003708 }
3709 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003710 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003711 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003712 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003713 }
3714 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003715 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003716 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003717 }
3718 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003719 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003720 assert(Type && "Missing type decl");
3721
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003722 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003723 getAsString());
3724 }
3725 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003726 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003727 assert(Template && "Missing template decl");
3728
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003729 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003730 }
3731
3732 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003733 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003734 assert(NS && "Missing namespace decl");
3735
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003736 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003737 }
3738
3739 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003740 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003741 assert(Field && "Missing member decl");
3742
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003743 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003744 }
3745
3746 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003747 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003748 assert(Label && "Missing label");
3749
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003750 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003751 }
3752
3753 case CXCursor_OverloadedDeclRef: {
3754 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003755 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3756 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003757 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003758 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003759 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003760 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003761 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003762 OverloadedTemplateStorage *Ovl
3763 = Storage.get<OverloadedTemplateStorage*>();
3764 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003765 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003766 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003767 }
3768
3769 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003770 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003771 assert(Var && "Missing variable decl");
3772
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003773 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003774 }
3775
3776 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003777 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003778 }
3779 }
3780
3781 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003782 const Expr *E = getCursorExpr(C);
3783
3784 if (C.kind == CXCursor_ObjCStringLiteral ||
3785 C.kind == CXCursor_StringLiteral) {
3786 const StringLiteral *SLit;
3787 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3788 SLit = OSL->getString();
3789 } else {
3790 SLit = cast<StringLiteral>(E);
3791 }
3792 SmallString<256> Buf;
3793 llvm::raw_svector_ostream OS(Buf);
3794 SLit->outputString(OS);
3795 return cxstring::createDup(OS.str());
3796 }
3797
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003798 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003799 if (D)
3800 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003801 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003802 }
3803
3804 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003805 const Stmt *S = getCursorStmt(C);
3806 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003807 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003808
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003809 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003810 }
3811
3812 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003813 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003814 ->getNameStart());
3815
3816 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003817 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003818 ->getNameStart());
3819
3820 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003821 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003822
3823 if (clang_isDeclaration(C.kind))
3824 return getDeclSpelling(getCursorDecl(C));
3825
3826 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003827 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003828 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003829 }
3830
3831 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003832 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003833 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003834 }
3835
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003836 if (C.kind == CXCursor_PackedAttr) {
3837 return cxstring::createRef("packed");
3838 }
3839
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00003840 if (C.kind == CXCursor_VisibilityAttr) {
3841 const VisibilityAttr *AA = cast<VisibilityAttr>(cxcursor::getCursorAttr(C));
3842 switch (AA->getVisibility()) {
3843 case VisibilityAttr::VisibilityType::Default:
3844 return cxstring::createRef("default");
3845 case VisibilityAttr::VisibilityType::Hidden:
3846 return cxstring::createRef("hidden");
3847 case VisibilityAttr::VisibilityType::Protected:
3848 return cxstring::createRef("protected");
3849 }
3850 llvm_unreachable("unknown visibility type");
3851 }
3852
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003853 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003854}
3855
3856CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3857 unsigned pieceIndex,
3858 unsigned options) {
3859 if (clang_Cursor_isNull(C))
3860 return clang_getNullRange();
3861
3862 ASTContext &Ctx = getCursorContext(C);
3863
3864 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003865 const Stmt *S = getCursorStmt(C);
3866 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003867 if (pieceIndex > 0)
3868 return clang_getNullRange();
3869 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3870 }
3871
3872 return clang_getNullRange();
3873 }
3874
3875 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003876 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003877 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3878 if (pieceIndex >= ME->getNumSelectorLocs())
3879 return clang_getNullRange();
3880 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3881 }
3882 }
3883
3884 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3885 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003886 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003887 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3888 if (pieceIndex >= MD->getNumSelectorLocs())
3889 return clang_getNullRange();
3890 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3891 }
3892 }
3893
3894 if (C.kind == CXCursor_ObjCCategoryDecl ||
3895 C.kind == CXCursor_ObjCCategoryImplDecl) {
3896 if (pieceIndex > 0)
3897 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003898 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003899 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3900 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003901 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003902 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3903 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3904 }
3905
3906 if (C.kind == CXCursor_ModuleImportDecl) {
3907 if (pieceIndex > 0)
3908 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003909 if (const ImportDecl *ImportD =
3910 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003911 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3912 if (!Locs.empty())
3913 return cxloc::translateSourceRange(Ctx,
3914 SourceRange(Locs.front(), Locs.back()));
3915 }
3916 return clang_getNullRange();
3917 }
3918
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00003919 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
3920 C.kind == CXCursor_ConversionFunction) {
3921 if (pieceIndex > 0)
3922 return clang_getNullRange();
3923 if (const FunctionDecl *FD =
3924 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
3925 DeclarationNameInfo FunctionName = FD->getNameInfo();
3926 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
3927 }
3928 return clang_getNullRange();
3929 }
3930
Guy Benyei11169dd2012-12-18 14:30:41 +00003931 // FIXME: A CXCursor_InclusionDirective should give the location of the
3932 // filename, but we don't keep track of this.
3933
3934 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3935 // but we don't keep track of this.
3936
3937 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3938 // but we don't keep track of this.
3939
3940 // Default handling, give the location of the cursor.
3941
3942 if (pieceIndex > 0)
3943 return clang_getNullRange();
3944
3945 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3946 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3947 return cxloc::translateSourceRange(Ctx, Loc);
3948}
3949
Eli Bendersky44a206f2014-07-31 18:04:56 +00003950CXString clang_Cursor_getMangling(CXCursor C) {
3951 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
3952 return cxstring::createEmpty();
3953
Eli Bendersky44a206f2014-07-31 18:04:56 +00003954 // Mangling only works for functions and variables.
Eli Bendersky79759592014-08-01 15:01:10 +00003955 const Decl *D = getCursorDecl(C);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003956 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
3957 return cxstring::createEmpty();
3958
Eli Bendersky79759592014-08-01 15:01:10 +00003959 // First apply frontend mangling.
Eli Bendersky44a206f2014-07-31 18:04:56 +00003960 const NamedDecl *ND = cast<NamedDecl>(D);
Eli Bendersky79759592014-08-01 15:01:10 +00003961 ASTContext &Ctx = ND->getASTContext();
3962 std::unique_ptr<MangleContext> MC(Ctx.createMangleContext());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003963
Eli Bendersky79759592014-08-01 15:01:10 +00003964 std::string FrontendBuf;
3965 llvm::raw_string_ostream FrontendBufOS(FrontendBuf);
Ehsan Akhgarif8d44de2015-10-08 00:01:20 +00003966 if (MC->shouldMangleDeclName(ND)) {
3967 MC->mangleName(ND, FrontendBufOS);
3968 } else {
3969 ND->printName(FrontendBufOS);
3970 }
Eli Bendersky44a206f2014-07-31 18:04:56 +00003971
Eli Bendersky79759592014-08-01 15:01:10 +00003972 // Now apply backend mangling.
3973 std::unique_ptr<llvm::DataLayout> DL(
Eric Christopher964a5f32015-08-05 23:48:05 +00003974 new llvm::DataLayout(Ctx.getTargetInfo().getDataLayoutString()));
Eli Bendersky79759592014-08-01 15:01:10 +00003975
3976 std::string FinalBuf;
3977 llvm::raw_string_ostream FinalBufOS(FinalBuf);
Rafael Espindolab633d202015-06-23 13:59:36 +00003978 llvm::Mangler::getNameWithPrefix(FinalBufOS, llvm::Twine(FrontendBufOS.str()),
3979 *DL);
Eli Bendersky79759592014-08-01 15:01:10 +00003980
3981 return cxstring::createDup(FinalBufOS.str());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003982}
3983
Saleem Abdulrasool60034432015-11-12 03:57:22 +00003984CXStringSet *clang_Cursor_getCXXManglings(CXCursor C) {
3985 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
3986 return nullptr;
3987
3988 const Decl *D = getCursorDecl(C);
3989 if (!(isa<CXXRecordDecl>(D) || isa<CXXMethodDecl>(D)))
3990 return nullptr;
3991
3992 const NamedDecl *ND = cast<NamedDecl>(D);
3993
3994 ASTContext &Ctx = ND->getASTContext();
3995 std::unique_ptr<MangleContext> M(Ctx.createMangleContext());
3996 std::unique_ptr<llvm::DataLayout> DL(
3997 new llvm::DataLayout(Ctx.getTargetInfo().getDataLayoutString()));
3998
3999 std::vector<std::string> Manglings;
4000
4001 auto hasDefaultCXXMethodCC = [](ASTContext &C, const CXXMethodDecl *MD) {
4002 auto DefaultCC = C.getDefaultCallingConvention(/*IsVariadic=*/false,
4003 /*IsCSSMethod=*/true);
4004 auto CC = MD->getType()->getAs<FunctionProtoType>()->getCallConv();
4005 return CC == DefaultCC;
4006 };
4007
4008 if (const auto *CD = dyn_cast_or_null<CXXConstructorDecl>(ND)) {
4009 Manglings.emplace_back(getMangledStructor(M, DL, CD, Ctor_Base));
4010
4011 if (Ctx.getTargetInfo().getCXXABI().isItaniumFamily())
4012 if (!CD->getParent()->isAbstract())
4013 Manglings.emplace_back(getMangledStructor(M, DL, CD, Ctor_Complete));
4014
4015 if (Ctx.getTargetInfo().getCXXABI().isMicrosoft())
4016 if (CD->hasAttr<DLLExportAttr>() && CD->isDefaultConstructor())
4017 if (!(hasDefaultCXXMethodCC(Ctx, CD) && CD->getNumParams() == 0))
4018 Manglings.emplace_back(getMangledStructor(M, DL, CD,
4019 Ctor_DefaultClosure));
4020 } else if (const auto *DD = dyn_cast_or_null<CXXDestructorDecl>(ND)) {
4021 Manglings.emplace_back(getMangledStructor(M, DL, DD, Dtor_Base));
4022 if (Ctx.getTargetInfo().getCXXABI().isItaniumFamily()) {
4023 Manglings.emplace_back(getMangledStructor(M, DL, DD, Dtor_Complete));
4024
4025 if (!DD->isVirtual())
4026 Manglings.emplace_back(getMangledStructor(M, DL, DD, Dtor_Deleting));
4027 }
4028 }
4029
4030 return cxstring::createSet(Manglings);
4031}
4032
Guy Benyei11169dd2012-12-18 14:30:41 +00004033CXString clang_getCursorDisplayName(CXCursor C) {
4034 if (!clang_isDeclaration(C.kind))
4035 return clang_getCursorSpelling(C);
4036
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004037 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004038 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004039 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004040
4041 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004042 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004043 D = FunTmpl->getTemplatedDecl();
4044
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004045 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004046 SmallString<64> Str;
4047 llvm::raw_svector_ostream OS(Str);
4048 OS << *Function;
4049 if (Function->getPrimaryTemplate())
4050 OS << "<>";
4051 OS << "(";
4052 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
4053 if (I)
4054 OS << ", ";
4055 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
4056 }
4057
4058 if (Function->isVariadic()) {
4059 if (Function->getNumParams())
4060 OS << ", ";
4061 OS << "...";
4062 }
4063 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004064 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004065 }
4066
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004067 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004068 SmallString<64> Str;
4069 llvm::raw_svector_ostream OS(Str);
4070 OS << *ClassTemplate;
4071 OS << "<";
4072 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
4073 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
4074 if (I)
4075 OS << ", ";
4076
4077 NamedDecl *Param = Params->getParam(I);
4078 if (Param->getIdentifier()) {
4079 OS << Param->getIdentifier()->getName();
4080 continue;
4081 }
4082
4083 // There is no parameter name, which makes this tricky. Try to come up
4084 // with something useful that isn't too long.
4085 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
4086 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
4087 else if (NonTypeTemplateParmDecl *NTTP
4088 = dyn_cast<NonTypeTemplateParmDecl>(Param))
4089 OS << NTTP->getType().getAsString(Policy);
4090 else
4091 OS << "template<...> class";
4092 }
4093
4094 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004095 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004096 }
4097
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004098 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00004099 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
4100 // If the type was explicitly written, use that.
4101 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004102 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00004103
Benjamin Kramer9170e912013-02-22 15:46:01 +00004104 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00004105 llvm::raw_svector_ostream OS(Str);
4106 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00004107 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00004108 ClassSpec->getTemplateArgs().data(),
4109 ClassSpec->getTemplateArgs().size(),
4110 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004111 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004112 }
4113
4114 return clang_getCursorSpelling(C);
4115}
4116
4117CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
4118 switch (Kind) {
4119 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004120 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004121 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004122 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004123 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004124 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004125 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004126 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004127 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004128 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004129 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004130 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004131 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004132 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004133 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004134 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004135 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004136 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004137 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004138 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004139 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004140 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004141 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004142 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004143 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004144 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004145 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004146 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004147 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004148 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004149 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004150 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004151 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004152 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004153 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004154 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004155 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004156 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004157 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004158 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00004159 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004160 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004161 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004162 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004163 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004164 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004165 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004166 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004167 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004168 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004169 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004170 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004171 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004172 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004173 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004174 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004175 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004176 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004177 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004178 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004179 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004180 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004181 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004182 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004183 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004184 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004185 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004186 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004187 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004188 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004189 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004190 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004191 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004192 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004193 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004194 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004195 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004196 return cxstring::createRef("ArraySubscriptExpr");
Alexey Bataev1a3320e2015-08-25 14:24:04 +00004197 case CXCursor_OMPArraySectionExpr:
4198 return cxstring::createRef("OMPArraySectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004199 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004200 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004201 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004202 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004203 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004204 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004205 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004206 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004207 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004208 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004209 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004210 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004211 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004212 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004213 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004214 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004215 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004216 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004217 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004218 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004219 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004220 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004221 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004222 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004223 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004224 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004225 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004226 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004227 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004228 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004229 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004230 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004231 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004232 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004233 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004234 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004235 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004236 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004237 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004238 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004239 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004240 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004241 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004242 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004243 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004244 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004245 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004246 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004247 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004248 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00004249 case CXCursor_ObjCSelfExpr:
4250 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004251 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004252 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004253 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004254 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004255 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004256 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004257 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004258 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004259 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004260 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004261 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004262 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004263 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004264 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004265 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004266 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004267 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004268 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004269 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004270 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004271 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004272 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004273 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004274 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004275 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004276 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004277 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004278 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004279 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004280 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004281 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004282 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004283 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004284 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004285 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004286 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004287 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004288 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004289 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004290 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004291 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004292 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004293 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004294 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004295 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004296 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004297 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004298 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004299 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004300 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004301 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004302 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004303 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004304 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004305 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004306 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004307 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004308 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004309 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004310 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004311 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004312 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004313 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004314 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004315 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004316 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004317 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004318 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004319 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004320 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004321 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004322 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004323 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004324 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004325 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004326 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004327 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004328 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004329 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004330 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004331 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004332 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004333 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004334 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004335 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004336 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004337 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004338 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00004339 case CXCursor_SEHLeaveStmt:
4340 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004341 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004342 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004343 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004344 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00004345 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004346 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00004347 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004348 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00004349 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004350 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00004351 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004352 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00004353 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004354 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004355 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004356 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004357 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004358 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004359 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004360 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004361 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004362 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004363 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004364 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004365 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004366 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004367 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004368 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004369 case CXCursor_PackedAttr:
4370 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00004371 case CXCursor_PureAttr:
4372 return cxstring::createRef("attribute(pure)");
4373 case CXCursor_ConstAttr:
4374 return cxstring::createRef("attribute(const)");
4375 case CXCursor_NoDuplicateAttr:
4376 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00004377 case CXCursor_CUDAConstantAttr:
4378 return cxstring::createRef("attribute(constant)");
4379 case CXCursor_CUDADeviceAttr:
4380 return cxstring::createRef("attribute(device)");
4381 case CXCursor_CUDAGlobalAttr:
4382 return cxstring::createRef("attribute(global)");
4383 case CXCursor_CUDAHostAttr:
4384 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00004385 case CXCursor_CUDASharedAttr:
4386 return cxstring::createRef("attribute(shared)");
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00004387 case CXCursor_VisibilityAttr:
4388 return cxstring::createRef("attribute(visibility)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004389 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004390 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004391 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004392 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00004393 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004394 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004395 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004396 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004397 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004398 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00004399 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004400 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00004401 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004402 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004403 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004404 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004405 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004406 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004407 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004408 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004409 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004410 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004411 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004412 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004413 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004414 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004415 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004416 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004417 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004418 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004419 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004420 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004421 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004422 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004423 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004424 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004425 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004426 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004427 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004428 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004429 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004430 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004431 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004432 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004433 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004434 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004435 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004436 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004437 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004438 return cxstring::createRef("OMPParallelDirective");
4439 case CXCursor_OMPSimdDirective:
4440 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004441 case CXCursor_OMPForDirective:
4442 return cxstring::createRef("OMPForDirective");
Alexander Musmanf82886e2014-09-18 05:12:34 +00004443 case CXCursor_OMPForSimdDirective:
4444 return cxstring::createRef("OMPForSimdDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004445 case CXCursor_OMPSectionsDirective:
4446 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004447 case CXCursor_OMPSectionDirective:
4448 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004449 case CXCursor_OMPSingleDirective:
4450 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004451 case CXCursor_OMPMasterDirective:
4452 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004453 case CXCursor_OMPCriticalDirective:
4454 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004455 case CXCursor_OMPParallelForDirective:
4456 return cxstring::createRef("OMPParallelForDirective");
Alexander Musmane4e893b2014-09-23 09:33:00 +00004457 case CXCursor_OMPParallelForSimdDirective:
4458 return cxstring::createRef("OMPParallelForSimdDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004459 case CXCursor_OMPParallelSectionsDirective:
4460 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004461 case CXCursor_OMPTaskDirective:
4462 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004463 case CXCursor_OMPTaskyieldDirective:
4464 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004465 case CXCursor_OMPBarrierDirective:
4466 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004467 case CXCursor_OMPTaskwaitDirective:
4468 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00004469 case CXCursor_OMPTaskgroupDirective:
4470 return cxstring::createRef("OMPTaskgroupDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00004471 case CXCursor_OMPFlushDirective:
4472 return cxstring::createRef("OMPFlushDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004473 case CXCursor_OMPOrderedDirective:
4474 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00004475 case CXCursor_OMPAtomicDirective:
4476 return cxstring::createRef("OMPAtomicDirective");
Alexey Bataev0bd520b2014-09-19 08:19:49 +00004477 case CXCursor_OMPTargetDirective:
4478 return cxstring::createRef("OMPTargetDirective");
Michael Wong65f367f2015-07-21 13:44:28 +00004479 case CXCursor_OMPTargetDataDirective:
4480 return cxstring::createRef("OMPTargetDataDirective");
Alexey Bataev13314bf2014-10-09 04:18:56 +00004481 case CXCursor_OMPTeamsDirective:
4482 return cxstring::createRef("OMPTeamsDirective");
Alexey Bataev6d4ed052015-07-01 06:57:41 +00004483 case CXCursor_OMPCancellationPointDirective:
4484 return cxstring::createRef("OMPCancellationPointDirective");
Alexey Bataev80909872015-07-02 11:25:17 +00004485 case CXCursor_OMPCancelDirective:
4486 return cxstring::createRef("OMPCancelDirective");
Alexey Bataev49f6e782015-12-01 04:18:41 +00004487 case CXCursor_OMPTaskLoopDirective:
4488 return cxstring::createRef("OMPTaskLoopDirective");
Alexey Bataev0a6ed842015-12-03 09:40:15 +00004489 case CXCursor_OMPTaskLoopSimdDirective:
4490 return cxstring::createRef("OMPTaskLoopSimdDirective");
Francisco Lopes da Silva975a9f62015-01-21 16:24:11 +00004491 case CXCursor_OverloadCandidate:
4492 return cxstring::createRef("OverloadCandidate");
Sergey Kalinichev8f3b1872015-11-15 13:48:32 +00004493 case CXCursor_TypeAliasTemplateDecl:
4494 return cxstring::createRef("TypeAliasTemplateDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004495 }
4496
4497 llvm_unreachable("Unhandled CXCursorKind");
4498}
4499
4500struct GetCursorData {
4501 SourceLocation TokenBeginLoc;
4502 bool PointsAtMacroArgExpansion;
4503 bool VisitedObjCPropertyImplDecl;
4504 SourceLocation VisitedDeclaratorDeclStartLoc;
4505 CXCursor &BestCursor;
4506
4507 GetCursorData(SourceManager &SM,
4508 SourceLocation tokenBegin, CXCursor &outputCursor)
4509 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4510 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4511 VisitedObjCPropertyImplDecl = false;
4512 }
4513};
4514
4515static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4516 CXCursor parent,
4517 CXClientData client_data) {
4518 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4519 CXCursor *BestCursor = &Data->BestCursor;
4520
4521 // If we point inside a macro argument we should provide info of what the
4522 // token is so use the actual cursor, don't replace it with a macro expansion
4523 // cursor.
4524 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4525 return CXChildVisit_Recurse;
4526
4527 if (clang_isDeclaration(cursor.kind)) {
4528 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004529 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004530 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4531 if (MD->isImplicit())
4532 return CXChildVisit_Break;
4533
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004534 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004535 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4536 // Check that when we have multiple @class references in the same line,
4537 // that later ones do not override the previous ones.
4538 // If we have:
4539 // @class Foo, Bar;
4540 // source ranges for both start at '@', so 'Bar' will end up overriding
4541 // 'Foo' even though the cursor location was at 'Foo'.
4542 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4543 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004544 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004545 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4546 if (PrevID != ID &&
4547 !PrevID->isThisDeclarationADefinition() &&
4548 !ID->isThisDeclarationADefinition())
4549 return CXChildVisit_Break;
4550 }
4551
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004552 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004553 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4554 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4555 // Check that when we have multiple declarators in the same line,
4556 // that later ones do not override the previous ones.
4557 // If we have:
4558 // int Foo, Bar;
4559 // source ranges for both start at 'int', so 'Bar' will end up overriding
4560 // 'Foo' even though the cursor location was at 'Foo'.
4561 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4562 return CXChildVisit_Break;
4563 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4564
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004565 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004566 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4567 (void)PropImp;
4568 // Check that when we have multiple @synthesize in the same line,
4569 // that later ones do not override the previous ones.
4570 // If we have:
4571 // @synthesize Foo, Bar;
4572 // source ranges for both start at '@', so 'Bar' will end up overriding
4573 // 'Foo' even though the cursor location was at 'Foo'.
4574 if (Data->VisitedObjCPropertyImplDecl)
4575 return CXChildVisit_Break;
4576 Data->VisitedObjCPropertyImplDecl = true;
4577 }
4578 }
4579
4580 if (clang_isExpression(cursor.kind) &&
4581 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004582 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004583 // Avoid having the cursor of an expression replace the declaration cursor
4584 // when the expression source range overlaps the declaration range.
4585 // This can happen for C++ constructor expressions whose range generally
4586 // include the variable declaration, e.g.:
4587 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4588 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4589 D->getLocation() == Data->TokenBeginLoc)
4590 return CXChildVisit_Break;
4591 }
4592 }
4593
4594 // If our current best cursor is the construction of a temporary object,
4595 // don't replace that cursor with a type reference, because we want
4596 // clang_getCursor() to point at the constructor.
4597 if (clang_isExpression(BestCursor->kind) &&
4598 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4599 cursor.kind == CXCursor_TypeRef) {
4600 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4601 // as having the actual point on the type reference.
4602 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4603 return CXChildVisit_Recurse;
4604 }
Douglas Gregore9d95f12015-07-07 03:57:35 +00004605
4606 // If we already have an Objective-C superclass reference, don't
4607 // update it further.
4608 if (BestCursor->kind == CXCursor_ObjCSuperClassRef)
4609 return CXChildVisit_Break;
4610
Guy Benyei11169dd2012-12-18 14:30:41 +00004611 *BestCursor = cursor;
4612 return CXChildVisit_Recurse;
4613}
4614
4615CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004616 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004617 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004618 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004619 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004620
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004621 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004622 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4623
4624 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4625 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4626
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004627 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004628 CXFile SearchFile;
4629 unsigned SearchLine, SearchColumn;
4630 CXFile ResultFile;
4631 unsigned ResultLine, ResultColumn;
4632 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4633 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4634 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004635
4636 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4637 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004638 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004639 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004640 SearchFileName = clang_getFileName(SearchFile);
4641 ResultFileName = clang_getFileName(ResultFile);
4642 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4643 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004644 *Log << llvm::format("(%s:%d:%d) = %s",
4645 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4646 clang_getCString(KindSpelling))
4647 << llvm::format("(%s:%d:%d):%s%s",
4648 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4649 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004650 clang_disposeString(SearchFileName);
4651 clang_disposeString(ResultFileName);
4652 clang_disposeString(KindSpelling);
4653 clang_disposeString(USR);
4654
4655 CXCursor Definition = clang_getCursorDefinition(Result);
4656 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4657 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4658 CXString DefinitionKindSpelling
4659 = clang_getCursorKindSpelling(Definition.kind);
4660 CXFile DefinitionFile;
4661 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004662 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004663 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004664 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004665 *Log << llvm::format(" -> %s(%s:%d:%d)",
4666 clang_getCString(DefinitionKindSpelling),
4667 clang_getCString(DefinitionFileName),
4668 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004669 clang_disposeString(DefinitionFileName);
4670 clang_disposeString(DefinitionKindSpelling);
4671 }
4672 }
4673
4674 return Result;
4675}
4676
4677CXCursor clang_getNullCursor(void) {
4678 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4679}
4680
4681unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004682 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4683 // can't set consistently. For example, when visiting a DeclStmt we will set
4684 // it but we don't set it on the result of clang_getCursorDefinition for
4685 // a reference of the same declaration.
4686 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4687 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4688 // to provide that kind of info.
4689 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004690 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004691 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004692 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004693
Guy Benyei11169dd2012-12-18 14:30:41 +00004694 return X == Y;
4695}
4696
4697unsigned clang_hashCursor(CXCursor C) {
4698 unsigned Index = 0;
4699 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4700 Index = 1;
4701
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004702 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004703 std::make_pair(C.kind, C.data[Index]));
4704}
4705
4706unsigned clang_isInvalid(enum CXCursorKind K) {
4707 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4708}
4709
4710unsigned clang_isDeclaration(enum CXCursorKind K) {
4711 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4712 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4713}
4714
4715unsigned clang_isReference(enum CXCursorKind K) {
4716 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4717}
4718
4719unsigned clang_isExpression(enum CXCursorKind K) {
4720 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4721}
4722
4723unsigned clang_isStatement(enum CXCursorKind K) {
4724 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4725}
4726
4727unsigned clang_isAttribute(enum CXCursorKind K) {
4728 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4729}
4730
4731unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4732 return K == CXCursor_TranslationUnit;
4733}
4734
4735unsigned clang_isPreprocessing(enum CXCursorKind K) {
4736 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4737}
4738
4739unsigned clang_isUnexposed(enum CXCursorKind K) {
4740 switch (K) {
4741 case CXCursor_UnexposedDecl:
4742 case CXCursor_UnexposedExpr:
4743 case CXCursor_UnexposedStmt:
4744 case CXCursor_UnexposedAttr:
4745 return true;
4746 default:
4747 return false;
4748 }
4749}
4750
4751CXCursorKind clang_getCursorKind(CXCursor C) {
4752 return C.kind;
4753}
4754
4755CXSourceLocation clang_getCursorLocation(CXCursor C) {
4756 if (clang_isReference(C.kind)) {
4757 switch (C.kind) {
4758 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004759 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004760 = getCursorObjCSuperClassRef(C);
4761 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4762 }
4763
4764 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004765 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004766 = getCursorObjCProtocolRef(C);
4767 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4768 }
4769
4770 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004771 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004772 = getCursorObjCClassRef(C);
4773 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4774 }
4775
4776 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004777 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004778 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4779 }
4780
4781 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004782 std::pair<const TemplateDecl *, SourceLocation> P =
4783 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004784 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4785 }
4786
4787 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004788 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004789 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4790 }
4791
4792 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004793 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004794 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4795 }
4796
4797 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004798 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004799 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4800 }
4801
4802 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004803 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004804 if (!BaseSpec)
4805 return clang_getNullLocation();
4806
4807 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4808 return cxloc::translateSourceLocation(getCursorContext(C),
4809 TSInfo->getTypeLoc().getBeginLoc());
4810
4811 return cxloc::translateSourceLocation(getCursorContext(C),
4812 BaseSpec->getLocStart());
4813 }
4814
4815 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004816 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004817 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4818 }
4819
4820 case CXCursor_OverloadedDeclRef:
4821 return cxloc::translateSourceLocation(getCursorContext(C),
4822 getCursorOverloadedDeclRef(C).second);
4823
4824 default:
4825 // FIXME: Need a way to enumerate all non-reference cases.
4826 llvm_unreachable("Missed a reference kind");
4827 }
4828 }
4829
4830 if (clang_isExpression(C.kind))
4831 return cxloc::translateSourceLocation(getCursorContext(C),
4832 getLocationFromExpr(getCursorExpr(C)));
4833
4834 if (clang_isStatement(C.kind))
4835 return cxloc::translateSourceLocation(getCursorContext(C),
4836 getCursorStmt(C)->getLocStart());
4837
4838 if (C.kind == CXCursor_PreprocessingDirective) {
4839 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4840 return cxloc::translateSourceLocation(getCursorContext(C), L);
4841 }
4842
4843 if (C.kind == CXCursor_MacroExpansion) {
4844 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004845 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004846 return cxloc::translateSourceLocation(getCursorContext(C), L);
4847 }
4848
4849 if (C.kind == CXCursor_MacroDefinition) {
4850 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4851 return cxloc::translateSourceLocation(getCursorContext(C), L);
4852 }
4853
4854 if (C.kind == CXCursor_InclusionDirective) {
4855 SourceLocation L
4856 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4857 return cxloc::translateSourceLocation(getCursorContext(C), L);
4858 }
4859
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004860 if (clang_isAttribute(C.kind)) {
4861 SourceLocation L
4862 = cxcursor::getCursorAttr(C)->getLocation();
4863 return cxloc::translateSourceLocation(getCursorContext(C), L);
4864 }
4865
Guy Benyei11169dd2012-12-18 14:30:41 +00004866 if (!clang_isDeclaration(C.kind))
4867 return clang_getNullLocation();
4868
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004869 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004870 if (!D)
4871 return clang_getNullLocation();
4872
4873 SourceLocation Loc = D->getLocation();
4874 // FIXME: Multiple variables declared in a single declaration
4875 // currently lack the information needed to correctly determine their
4876 // ranges when accounting for the type-specifier. We use context
4877 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4878 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004879 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004880 if (!cxcursor::isFirstInDeclGroup(C))
4881 Loc = VD->getLocation();
4882 }
4883
4884 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004885 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004886 Loc = MD->getSelectorStartLoc();
4887
4888 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4889}
4890
4891} // end extern "C"
4892
4893CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4894 assert(TU);
4895
4896 // Guard against an invalid SourceLocation, or we may assert in one
4897 // of the following calls.
4898 if (SLoc.isInvalid())
4899 return clang_getNullCursor();
4900
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004901 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004902
4903 // Translate the given source location to make it point at the beginning of
4904 // the token under the cursor.
4905 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4906 CXXUnit->getASTContext().getLangOpts());
4907
4908 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4909 if (SLoc.isValid()) {
4910 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4911 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4912 /*VisitPreprocessorLast=*/true,
4913 /*VisitIncludedEntities=*/false,
4914 SourceLocation(SLoc));
4915 CursorVis.visitFileRegion();
4916 }
4917
4918 return Result;
4919}
4920
4921static SourceRange getRawCursorExtent(CXCursor C) {
4922 if (clang_isReference(C.kind)) {
4923 switch (C.kind) {
4924 case CXCursor_ObjCSuperClassRef:
4925 return getCursorObjCSuperClassRef(C).second;
4926
4927 case CXCursor_ObjCProtocolRef:
4928 return getCursorObjCProtocolRef(C).second;
4929
4930 case CXCursor_ObjCClassRef:
4931 return getCursorObjCClassRef(C).second;
4932
4933 case CXCursor_TypeRef:
4934 return getCursorTypeRef(C).second;
4935
4936 case CXCursor_TemplateRef:
4937 return getCursorTemplateRef(C).second;
4938
4939 case CXCursor_NamespaceRef:
4940 return getCursorNamespaceRef(C).second;
4941
4942 case CXCursor_MemberRef:
4943 return getCursorMemberRef(C).second;
4944
4945 case CXCursor_CXXBaseSpecifier:
4946 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4947
4948 case CXCursor_LabelRef:
4949 return getCursorLabelRef(C).second;
4950
4951 case CXCursor_OverloadedDeclRef:
4952 return getCursorOverloadedDeclRef(C).second;
4953
4954 case CXCursor_VariableRef:
4955 return getCursorVariableRef(C).second;
4956
4957 default:
4958 // FIXME: Need a way to enumerate all non-reference cases.
4959 llvm_unreachable("Missed a reference kind");
4960 }
4961 }
4962
4963 if (clang_isExpression(C.kind))
4964 return getCursorExpr(C)->getSourceRange();
4965
4966 if (clang_isStatement(C.kind))
4967 return getCursorStmt(C)->getSourceRange();
4968
4969 if (clang_isAttribute(C.kind))
4970 return getCursorAttr(C)->getRange();
4971
4972 if (C.kind == CXCursor_PreprocessingDirective)
4973 return cxcursor::getCursorPreprocessingDirective(C);
4974
4975 if (C.kind == CXCursor_MacroExpansion) {
4976 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004977 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004978 return TU->mapRangeFromPreamble(Range);
4979 }
4980
4981 if (C.kind == CXCursor_MacroDefinition) {
4982 ASTUnit *TU = getCursorASTUnit(C);
4983 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4984 return TU->mapRangeFromPreamble(Range);
4985 }
4986
4987 if (C.kind == CXCursor_InclusionDirective) {
4988 ASTUnit *TU = getCursorASTUnit(C);
4989 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4990 return TU->mapRangeFromPreamble(Range);
4991 }
4992
4993 if (C.kind == CXCursor_TranslationUnit) {
4994 ASTUnit *TU = getCursorASTUnit(C);
4995 FileID MainID = TU->getSourceManager().getMainFileID();
4996 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4997 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4998 return SourceRange(Start, End);
4999 }
5000
5001 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005002 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005003 if (!D)
5004 return SourceRange();
5005
5006 SourceRange R = D->getSourceRange();
5007 // FIXME: Multiple variables declared in a single declaration
5008 // currently lack the information needed to correctly determine their
5009 // ranges when accounting for the type-specifier. We use context
5010 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
5011 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005012 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005013 if (!cxcursor::isFirstInDeclGroup(C))
5014 R.setBegin(VD->getLocation());
5015 }
5016 return R;
5017 }
5018 return SourceRange();
5019}
5020
5021/// \brief Retrieves the "raw" cursor extent, which is then extended to include
5022/// the decl-specifier-seq for declarations.
5023static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
5024 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005025 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005026 if (!D)
5027 return SourceRange();
5028
5029 SourceRange R = D->getSourceRange();
5030
5031 // Adjust the start of the location for declarations preceded by
5032 // declaration specifiers.
5033 SourceLocation StartLoc;
5034 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
5035 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
5036 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005037 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005038 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
5039 StartLoc = TI->getTypeLoc().getLocStart();
5040 }
5041
5042 if (StartLoc.isValid() && R.getBegin().isValid() &&
5043 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
5044 R.setBegin(StartLoc);
5045
5046 // FIXME: Multiple variables declared in a single declaration
5047 // currently lack the information needed to correctly determine their
5048 // ranges when accounting for the type-specifier. We use context
5049 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
5050 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005051 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005052 if (!cxcursor::isFirstInDeclGroup(C))
5053 R.setBegin(VD->getLocation());
5054 }
5055
5056 return R;
5057 }
5058
5059 return getRawCursorExtent(C);
5060}
5061
5062extern "C" {
5063
5064CXSourceRange clang_getCursorExtent(CXCursor C) {
5065 SourceRange R = getRawCursorExtent(C);
5066 if (R.isInvalid())
5067 return clang_getNullRange();
5068
5069 return cxloc::translateSourceRange(getCursorContext(C), R);
5070}
5071
5072CXCursor clang_getCursorReferenced(CXCursor C) {
5073 if (clang_isInvalid(C.kind))
5074 return clang_getNullCursor();
5075
5076 CXTranslationUnit tu = getCursorTU(C);
5077 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005078 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005079 if (!D)
5080 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005081 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005082 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005083 if (const ObjCPropertyImplDecl *PropImpl =
5084 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005085 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
5086 return MakeCXCursor(Property, tu);
5087
5088 return C;
5089 }
5090
5091 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005092 const Expr *E = getCursorExpr(C);
5093 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00005094 if (D) {
5095 CXCursor declCursor = MakeCXCursor(D, tu);
5096 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
5097 declCursor);
5098 return declCursor;
5099 }
5100
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005101 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00005102 return MakeCursorOverloadedDeclRef(Ovl, tu);
5103
5104 return clang_getNullCursor();
5105 }
5106
5107 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005108 const Stmt *S = getCursorStmt(C);
5109 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00005110 if (LabelDecl *label = Goto->getLabel())
5111 if (LabelStmt *labelS = label->getStmt())
5112 return MakeCXCursor(labelS, getCursorDecl(C), tu);
5113
5114 return clang_getNullCursor();
5115 }
Richard Smith66a81862015-05-04 02:25:31 +00005116
Guy Benyei11169dd2012-12-18 14:30:41 +00005117 if (C.kind == CXCursor_MacroExpansion) {
Richard Smith66a81862015-05-04 02:25:31 +00005118 if (const MacroDefinitionRecord *Def =
5119 getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005120 return MakeMacroDefinitionCursor(Def, tu);
5121 }
5122
5123 if (!clang_isReference(C.kind))
5124 return clang_getNullCursor();
5125
5126 switch (C.kind) {
5127 case CXCursor_ObjCSuperClassRef:
5128 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
5129
5130 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005131 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
5132 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005133 return MakeCXCursor(Def, tu);
5134
5135 return MakeCXCursor(Prot, tu);
5136 }
5137
5138 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005139 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
5140 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005141 return MakeCXCursor(Def, tu);
5142
5143 return MakeCXCursor(Class, tu);
5144 }
5145
5146 case CXCursor_TypeRef:
5147 return MakeCXCursor(getCursorTypeRef(C).first, tu );
5148
5149 case CXCursor_TemplateRef:
5150 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
5151
5152 case CXCursor_NamespaceRef:
5153 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
5154
5155 case CXCursor_MemberRef:
5156 return MakeCXCursor(getCursorMemberRef(C).first, tu );
5157
5158 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005159 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005160 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
5161 tu ));
5162 }
5163
5164 case CXCursor_LabelRef:
5165 // FIXME: We end up faking the "parent" declaration here because we
5166 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005167 return MakeCXCursor(getCursorLabelRef(C).first,
5168 cxtu::getASTUnit(tu)->getASTContext()
5169 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00005170 tu);
5171
5172 case CXCursor_OverloadedDeclRef:
5173 return C;
5174
5175 case CXCursor_VariableRef:
5176 return MakeCXCursor(getCursorVariableRef(C).first, tu);
5177
5178 default:
5179 // We would prefer to enumerate all non-reference cursor kinds here.
5180 llvm_unreachable("Unhandled reference cursor kind");
5181 }
5182}
5183
5184CXCursor clang_getCursorDefinition(CXCursor C) {
5185 if (clang_isInvalid(C.kind))
5186 return clang_getNullCursor();
5187
5188 CXTranslationUnit TU = getCursorTU(C);
5189
5190 bool WasReference = false;
5191 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
5192 C = clang_getCursorReferenced(C);
5193 WasReference = true;
5194 }
5195
5196 if (C.kind == CXCursor_MacroExpansion)
5197 return clang_getCursorReferenced(C);
5198
5199 if (!clang_isDeclaration(C.kind))
5200 return clang_getNullCursor();
5201
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005202 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005203 if (!D)
5204 return clang_getNullCursor();
5205
5206 switch (D->getKind()) {
5207 // Declaration kinds that don't really separate the notions of
5208 // declaration and definition.
5209 case Decl::Namespace:
5210 case Decl::Typedef:
5211 case Decl::TypeAlias:
5212 case Decl::TypeAliasTemplate:
5213 case Decl::TemplateTypeParm:
5214 case Decl::EnumConstant:
5215 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00005216 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005217 case Decl::IndirectField:
5218 case Decl::ObjCIvar:
5219 case Decl::ObjCAtDefsField:
5220 case Decl::ImplicitParam:
5221 case Decl::ParmVar:
5222 case Decl::NonTypeTemplateParm:
5223 case Decl::TemplateTemplateParm:
5224 case Decl::ObjCCategoryImpl:
5225 case Decl::ObjCImplementation:
5226 case Decl::AccessSpec:
5227 case Decl::LinkageSpec:
5228 case Decl::ObjCPropertyImpl:
5229 case Decl::FileScopeAsm:
5230 case Decl::StaticAssert:
5231 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00005232 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00005233 case Decl::Label: // FIXME: Is this right??
5234 case Decl::ClassScopeFunctionSpecialization:
5235 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00005236 case Decl::OMPThreadPrivate:
Douglas Gregor85f3f952015-07-07 03:57:15 +00005237 case Decl::ObjCTypeParam:
David Majnemerd9b1a4f2015-11-04 03:40:30 +00005238 case Decl::BuiltinTemplate:
Guy Benyei11169dd2012-12-18 14:30:41 +00005239 return C;
5240
5241 // Declaration kinds that don't make any sense here, but are
5242 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00005243 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005244 case Decl::TranslationUnit:
Richard Smithf19e1272015-03-07 00:04:49 +00005245 case Decl::ExternCContext:
Guy Benyei11169dd2012-12-18 14:30:41 +00005246 break;
5247
5248 // Declaration kinds for which the definition is not resolvable.
5249 case Decl::UnresolvedUsingTypename:
5250 case Decl::UnresolvedUsingValue:
5251 break;
5252
5253 case Decl::UsingDirective:
5254 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
5255 TU);
5256
5257 case Decl::NamespaceAlias:
5258 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
5259
5260 case Decl::Enum:
5261 case Decl::Record:
5262 case Decl::CXXRecord:
5263 case Decl::ClassTemplateSpecialization:
5264 case Decl::ClassTemplatePartialSpecialization:
5265 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
5266 return MakeCXCursor(Def, TU);
5267 return clang_getNullCursor();
5268
5269 case Decl::Function:
5270 case Decl::CXXMethod:
5271 case Decl::CXXConstructor:
5272 case Decl::CXXDestructor:
5273 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00005274 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005275 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00005276 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005277 return clang_getNullCursor();
5278 }
5279
Larisse Voufo39a1e502013-08-06 01:03:05 +00005280 case Decl::Var:
5281 case Decl::VarTemplateSpecialization:
5282 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00005283 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005284 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005285 return MakeCXCursor(Def, TU);
5286 return clang_getNullCursor();
5287 }
5288
5289 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00005290 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005291 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
5292 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
5293 return clang_getNullCursor();
5294 }
5295
5296 case Decl::ClassTemplate: {
5297 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
5298 ->getDefinition())
5299 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
5300 TU);
5301 return clang_getNullCursor();
5302 }
5303
Larisse Voufo39a1e502013-08-06 01:03:05 +00005304 case Decl::VarTemplate: {
5305 if (VarDecl *Def =
5306 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
5307 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
5308 return clang_getNullCursor();
5309 }
5310
Guy Benyei11169dd2012-12-18 14:30:41 +00005311 case Decl::Using:
5312 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
5313 D->getLocation(), TU);
5314
5315 case Decl::UsingShadow:
5316 return clang_getCursorDefinition(
5317 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
5318 TU));
5319
5320 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005321 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005322 if (Method->isThisDeclarationADefinition())
5323 return C;
5324
5325 // Dig out the method definition in the associated
5326 // @implementation, if we have it.
5327 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005328 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005329 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
5330 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
5331 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
5332 Method->isInstanceMethod()))
5333 if (Def->isThisDeclarationADefinition())
5334 return MakeCXCursor(Def, TU);
5335
5336 return clang_getNullCursor();
5337 }
5338
5339 case Decl::ObjCCategory:
5340 if (ObjCCategoryImplDecl *Impl
5341 = cast<ObjCCategoryDecl>(D)->getImplementation())
5342 return MakeCXCursor(Impl, TU);
5343 return clang_getNullCursor();
5344
5345 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005346 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005347 return MakeCXCursor(Def, TU);
5348 return clang_getNullCursor();
5349
5350 case Decl::ObjCInterface: {
5351 // There are two notions of a "definition" for an Objective-C
5352 // class: the interface and its implementation. When we resolved a
5353 // reference to an Objective-C class, produce the @interface as
5354 // the definition; when we were provided with the interface,
5355 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005356 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005357 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005358 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005359 return MakeCXCursor(Def, TU);
5360 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
5361 return MakeCXCursor(Impl, TU);
5362 return clang_getNullCursor();
5363 }
5364
5365 case Decl::ObjCProperty:
5366 // FIXME: We don't really know where to find the
5367 // ObjCPropertyImplDecls that implement this property.
5368 return clang_getNullCursor();
5369
5370 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005371 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005372 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005373 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005374 return MakeCXCursor(Def, TU);
5375
5376 return clang_getNullCursor();
5377
5378 case Decl::Friend:
5379 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
5380 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5381 return clang_getNullCursor();
5382
5383 case Decl::FriendTemplate:
5384 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
5385 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5386 return clang_getNullCursor();
5387 }
5388
5389 return clang_getNullCursor();
5390}
5391
5392unsigned clang_isCursorDefinition(CXCursor C) {
5393 if (!clang_isDeclaration(C.kind))
5394 return 0;
5395
5396 return clang_getCursorDefinition(C) == C;
5397}
5398
5399CXCursor clang_getCanonicalCursor(CXCursor C) {
5400 if (!clang_isDeclaration(C.kind))
5401 return C;
5402
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005403 if (const Decl *D = getCursorDecl(C)) {
5404 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005405 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5406 return MakeCXCursor(CatD, getCursorTU(C));
5407
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005408 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5409 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00005410 return MakeCXCursor(IFD, getCursorTU(C));
5411
5412 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5413 }
5414
5415 return C;
5416}
5417
5418int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5419 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5420}
5421
5422unsigned clang_getNumOverloadedDecls(CXCursor C) {
5423 if (C.kind != CXCursor_OverloadedDeclRef)
5424 return 0;
5425
5426 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005427 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005428 return E->getNumDecls();
5429
5430 if (OverloadedTemplateStorage *S
5431 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5432 return S->size();
5433
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005434 const Decl *D = Storage.get<const Decl *>();
5435 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005436 return Using->shadow_size();
5437
5438 return 0;
5439}
5440
5441CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5442 if (cursor.kind != CXCursor_OverloadedDeclRef)
5443 return clang_getNullCursor();
5444
5445 if (index >= clang_getNumOverloadedDecls(cursor))
5446 return clang_getNullCursor();
5447
5448 CXTranslationUnit TU = getCursorTU(cursor);
5449 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005450 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005451 return MakeCXCursor(E->decls_begin()[index], TU);
5452
5453 if (OverloadedTemplateStorage *S
5454 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5455 return MakeCXCursor(S->begin()[index], TU);
5456
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005457 const Decl *D = Storage.get<const Decl *>();
5458 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005459 // FIXME: This is, unfortunately, linear time.
5460 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5461 std::advance(Pos, index);
5462 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5463 }
5464
5465 return clang_getNullCursor();
5466}
5467
5468void clang_getDefinitionSpellingAndExtent(CXCursor C,
5469 const char **startBuf,
5470 const char **endBuf,
5471 unsigned *startLine,
5472 unsigned *startColumn,
5473 unsigned *endLine,
5474 unsigned *endColumn) {
5475 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005476 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005477 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5478
5479 SourceManager &SM = FD->getASTContext().getSourceManager();
5480 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5481 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5482 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5483 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5484 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5485 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5486}
5487
5488
5489CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5490 unsigned PieceIndex) {
5491 RefNamePieces Pieces;
5492
5493 switch (C.kind) {
5494 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005495 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005496 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5497 E->getQualifierLoc().getSourceRange());
5498 break;
5499
5500 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005501 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005502 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
5503 E->getQualifierLoc().getSourceRange(),
5504 E->getOptionalExplicitTemplateArgs());
5505 break;
5506
5507 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005508 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005509 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005510 const Expr *Callee = OCE->getCallee();
5511 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005512 Callee = ICE->getSubExpr();
5513
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005514 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005515 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5516 DRE->getQualifierLoc().getSourceRange());
5517 }
5518 break;
5519
5520 default:
5521 break;
5522 }
5523
5524 if (Pieces.empty()) {
5525 if (PieceIndex == 0)
5526 return clang_getCursorExtent(C);
5527 } else if (PieceIndex < Pieces.size()) {
5528 SourceRange R = Pieces[PieceIndex];
5529 if (R.isValid())
5530 return cxloc::translateSourceRange(getCursorContext(C), R);
5531 }
5532
5533 return clang_getNullRange();
5534}
5535
5536void clang_enableStackTraces(void) {
5537 llvm::sys::PrintStackTraceOnErrorSignal();
5538}
5539
5540void clang_executeOnThread(void (*fn)(void*), void *user_data,
5541 unsigned stack_size) {
5542 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5543}
5544
5545} // end: extern "C"
5546
5547//===----------------------------------------------------------------------===//
5548// Token-based Operations.
5549//===----------------------------------------------------------------------===//
5550
5551/* CXToken layout:
5552 * int_data[0]: a CXTokenKind
5553 * int_data[1]: starting token location
5554 * int_data[2]: token length
5555 * int_data[3]: reserved
5556 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5557 * otherwise unused.
5558 */
5559extern "C" {
5560
5561CXTokenKind clang_getTokenKind(CXToken CXTok) {
5562 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5563}
5564
5565CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5566 switch (clang_getTokenKind(CXTok)) {
5567 case CXToken_Identifier:
5568 case CXToken_Keyword:
5569 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005570 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005571 ->getNameStart());
5572
5573 case CXToken_Literal: {
5574 // We have stashed the starting pointer in the ptr_data field. Use it.
5575 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005576 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005577 }
5578
5579 case CXToken_Punctuation:
5580 case CXToken_Comment:
5581 break;
5582 }
5583
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005584 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005585 LOG_BAD_TU(TU);
5586 return cxstring::createEmpty();
5587 }
5588
Guy Benyei11169dd2012-12-18 14:30:41 +00005589 // We have to find the starting buffer pointer the hard way, by
5590 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005591 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005592 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005593 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005594
5595 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5596 std::pair<FileID, unsigned> LocInfo
5597 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5598 bool Invalid = false;
5599 StringRef Buffer
5600 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5601 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005602 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005603
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005604 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005605}
5606
5607CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005608 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005609 LOG_BAD_TU(TU);
5610 return clang_getNullLocation();
5611 }
5612
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005613 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005614 if (!CXXUnit)
5615 return clang_getNullLocation();
5616
5617 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5618 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5619}
5620
5621CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005622 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005623 LOG_BAD_TU(TU);
5624 return clang_getNullRange();
5625 }
5626
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005627 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005628 if (!CXXUnit)
5629 return clang_getNullRange();
5630
5631 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5632 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5633}
5634
5635static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5636 SmallVectorImpl<CXToken> &CXTokens) {
5637 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5638 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005639 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005640 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005641 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005642
5643 // Cannot tokenize across files.
5644 if (BeginLocInfo.first != EndLocInfo.first)
5645 return;
5646
5647 // Create a lexer
5648 bool Invalid = false;
5649 StringRef Buffer
5650 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5651 if (Invalid)
5652 return;
5653
5654 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5655 CXXUnit->getASTContext().getLangOpts(),
5656 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5657 Lex.SetCommentRetentionState(true);
5658
5659 // Lex tokens until we hit the end of the range.
5660 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5661 Token Tok;
5662 bool previousWasAt = false;
5663 do {
5664 // Lex the next token
5665 Lex.LexFromRawLexer(Tok);
5666 if (Tok.is(tok::eof))
5667 break;
5668
5669 // Initialize the CXToken.
5670 CXToken CXTok;
5671
5672 // - Common fields
5673 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5674 CXTok.int_data[2] = Tok.getLength();
5675 CXTok.int_data[3] = 0;
5676
5677 // - Kind-specific fields
5678 if (Tok.isLiteral()) {
5679 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005680 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005681 } else if (Tok.is(tok::raw_identifier)) {
5682 // Lookup the identifier to determine whether we have a keyword.
5683 IdentifierInfo *II
5684 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5685
5686 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5687 CXTok.int_data[0] = CXToken_Keyword;
5688 }
5689 else {
5690 CXTok.int_data[0] = Tok.is(tok::identifier)
5691 ? CXToken_Identifier
5692 : CXToken_Keyword;
5693 }
5694 CXTok.ptr_data = II;
5695 } else if (Tok.is(tok::comment)) {
5696 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005697 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005698 } else {
5699 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005700 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005701 }
5702 CXTokens.push_back(CXTok);
5703 previousWasAt = Tok.is(tok::at);
5704 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5705}
5706
5707void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5708 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005709 LOG_FUNC_SECTION {
5710 *Log << TU << ' ' << Range;
5711 }
5712
Guy Benyei11169dd2012-12-18 14:30:41 +00005713 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005714 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005715 if (NumTokens)
5716 *NumTokens = 0;
5717
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005718 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005719 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005720 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005721 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005722
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005723 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005724 if (!CXXUnit || !Tokens || !NumTokens)
5725 return;
5726
5727 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5728
5729 SourceRange R = cxloc::translateCXSourceRange(Range);
5730 if (R.isInvalid())
5731 return;
5732
5733 SmallVector<CXToken, 32> CXTokens;
5734 getTokens(CXXUnit, R, CXTokens);
5735
5736 if (CXTokens.empty())
5737 return;
5738
5739 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5740 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5741 *NumTokens = CXTokens.size();
5742}
5743
5744void clang_disposeTokens(CXTranslationUnit TU,
5745 CXToken *Tokens, unsigned NumTokens) {
5746 free(Tokens);
5747}
5748
5749} // end: extern "C"
5750
5751//===----------------------------------------------------------------------===//
5752// Token annotation APIs.
5753//===----------------------------------------------------------------------===//
5754
Guy Benyei11169dd2012-12-18 14:30:41 +00005755static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5756 CXCursor parent,
5757 CXClientData client_data);
5758static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5759 CXClientData client_data);
5760
5761namespace {
5762class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005763 CXToken *Tokens;
5764 CXCursor *Cursors;
5765 unsigned NumTokens;
5766 unsigned TokIdx;
5767 unsigned PreprocessingTokIdx;
5768 CursorVisitor AnnotateVis;
5769 SourceManager &SrcMgr;
5770 bool HasContextSensitiveKeywords;
5771
5772 struct PostChildrenInfo {
5773 CXCursor Cursor;
5774 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005775 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005776 unsigned BeforeChildrenTokenIdx;
5777 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005778 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005779
5780 CXToken &getTok(unsigned Idx) {
5781 assert(Idx < NumTokens);
5782 return Tokens[Idx];
5783 }
5784 const CXToken &getTok(unsigned Idx) const {
5785 assert(Idx < NumTokens);
5786 return Tokens[Idx];
5787 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005788 bool MoreTokens() const { return TokIdx < NumTokens; }
5789 unsigned NextToken() const { return TokIdx; }
5790 void AdvanceToken() { ++TokIdx; }
5791 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005792 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005793 }
5794 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005795 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005796 }
5797 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005798 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005799 }
5800
5801 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005802 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005803 SourceRange);
5804
5805public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005806 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005807 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005808 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005809 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005810 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005811 AnnotateTokensVisitor, this,
5812 /*VisitPreprocessorLast=*/true,
5813 /*VisitIncludedEntities=*/false,
5814 RegionOfInterest,
5815 /*VisitDeclsOnly=*/false,
5816 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005817 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005818 HasContextSensitiveKeywords(false) { }
5819
5820 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5821 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5822 bool postVisitChildren(CXCursor cursor);
5823 void AnnotateTokens();
5824
5825 /// \brief Determine whether the annotator saw any cursors that have
5826 /// context-sensitive keywords.
5827 bool hasContextSensitiveKeywords() const {
5828 return HasContextSensitiveKeywords;
5829 }
5830
5831 ~AnnotateTokensWorker() {
5832 assert(PostChildrenInfos.empty());
5833 }
5834};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00005835}
Guy Benyei11169dd2012-12-18 14:30:41 +00005836
5837void AnnotateTokensWorker::AnnotateTokens() {
5838 // Walk the AST within the region of interest, annotating tokens
5839 // along the way.
5840 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005841}
Guy Benyei11169dd2012-12-18 14:30:41 +00005842
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005843static inline void updateCursorAnnotation(CXCursor &Cursor,
5844 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005845 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005846 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005847 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005848}
5849
5850/// \brief It annotates and advances tokens with a cursor until the comparison
5851//// between the cursor location and the source range is the same as
5852/// \arg compResult.
5853///
5854/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5855/// Pass RangeOverlap to annotate tokens inside a range.
5856void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5857 RangeComparisonResult compResult,
5858 SourceRange range) {
5859 while (MoreTokens()) {
5860 const unsigned I = NextToken();
5861 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005862 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5863 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005864
5865 SourceLocation TokLoc = GetTokenLoc(I);
5866 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005867 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005868 AdvanceToken();
5869 continue;
5870 }
5871 break;
5872 }
5873}
5874
5875/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005876/// \returns true if it advanced beyond all macro tokens, false otherwise.
5877bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005878 CXCursor updateC,
5879 RangeComparisonResult compResult,
5880 SourceRange range) {
5881 assert(MoreTokens());
5882 assert(isFunctionMacroToken(NextToken()) &&
5883 "Should be called only for macro arg tokens");
5884
5885 // This works differently than annotateAndAdvanceTokens; because expanded
5886 // macro arguments can have arbitrary translation-unit source order, we do not
5887 // advance the token index one by one until a token fails the range test.
5888 // We only advance once past all of the macro arg tokens if all of them
5889 // pass the range test. If one of them fails we keep the token index pointing
5890 // at the start of the macro arg tokens so that the failing token will be
5891 // annotated by a subsequent annotation try.
5892
5893 bool atLeastOneCompFail = false;
5894
5895 unsigned I = NextToken();
5896 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5897 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5898 if (TokLoc.isFileID())
5899 continue; // not macro arg token, it's parens or comma.
5900 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5901 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5902 Cursors[I] = updateC;
5903 } else
5904 atLeastOneCompFail = true;
5905 }
5906
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005907 if (atLeastOneCompFail)
5908 return false;
5909
5910 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5911 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005912}
5913
5914enum CXChildVisitResult
5915AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005916 SourceRange cursorRange = getRawCursorExtent(cursor);
5917 if (cursorRange.isInvalid())
5918 return CXChildVisit_Recurse;
5919
5920 if (!HasContextSensitiveKeywords) {
5921 // Objective-C properties can have context-sensitive keywords.
5922 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005923 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005924 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5925 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5926 }
5927 // Objective-C methods can have context-sensitive keywords.
5928 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5929 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005930 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005931 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5932 if (Method->getObjCDeclQualifier())
5933 HasContextSensitiveKeywords = true;
5934 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005935 for (const auto *P : Method->params()) {
5936 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005937 HasContextSensitiveKeywords = true;
5938 break;
5939 }
5940 }
5941 }
5942 }
5943 }
5944 // C++ methods can have context-sensitive keywords.
5945 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005946 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005947 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5948 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5949 HasContextSensitiveKeywords = true;
5950 }
5951 }
5952 // C++ classes can have context-sensitive keywords.
5953 else if (cursor.kind == CXCursor_StructDecl ||
5954 cursor.kind == CXCursor_ClassDecl ||
5955 cursor.kind == CXCursor_ClassTemplate ||
5956 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005957 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005958 if (D->hasAttr<FinalAttr>())
5959 HasContextSensitiveKeywords = true;
5960 }
5961 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005962
5963 // Don't override a property annotation with its getter/setter method.
5964 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5965 parent.kind == CXCursor_ObjCPropertyDecl)
5966 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005967
5968 if (clang_isPreprocessing(cursor.kind)) {
5969 // Items in the preprocessing record are kept separate from items in
5970 // declarations, so we keep a separate token index.
5971 unsigned SavedTokIdx = TokIdx;
5972 TokIdx = PreprocessingTokIdx;
5973
5974 // Skip tokens up until we catch up to the beginning of the preprocessing
5975 // entry.
5976 while (MoreTokens()) {
5977 const unsigned I = NextToken();
5978 SourceLocation TokLoc = GetTokenLoc(I);
5979 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5980 case RangeBefore:
5981 AdvanceToken();
5982 continue;
5983 case RangeAfter:
5984 case RangeOverlap:
5985 break;
5986 }
5987 break;
5988 }
5989
5990 // Look at all of the tokens within this range.
5991 while (MoreTokens()) {
5992 const unsigned I = NextToken();
5993 SourceLocation TokLoc = GetTokenLoc(I);
5994 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5995 case RangeBefore:
5996 llvm_unreachable("Infeasible");
5997 case RangeAfter:
5998 break;
5999 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006000 // For macro expansions, just note where the beginning of the macro
6001 // expansion occurs.
6002 if (cursor.kind == CXCursor_MacroExpansion) {
6003 if (TokLoc == cursorRange.getBegin())
6004 Cursors[I] = cursor;
6005 AdvanceToken();
6006 break;
6007 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006008 // We may have already annotated macro names inside macro definitions.
6009 if (Cursors[I].kind != CXCursor_MacroExpansion)
6010 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00006011 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00006012 continue;
6013 }
6014 break;
6015 }
6016
6017 // Save the preprocessing token index; restore the non-preprocessing
6018 // token index.
6019 PreprocessingTokIdx = TokIdx;
6020 TokIdx = SavedTokIdx;
6021 return CXChildVisit_Recurse;
6022 }
6023
6024 if (cursorRange.isInvalid())
6025 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006026
6027 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00006028 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006029 const enum CXCursorKind K = clang_getCursorKind(parent);
6030 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006031 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
6032 // Attributes are annotated out-of-order, skip tokens until we reach it.
6033 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00006034 ? clang_getNullCursor() : parent;
6035
6036 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
6037
6038 // Avoid having the cursor of an expression "overwrite" the annotation of the
6039 // variable declaration that it belongs to.
6040 // This can happen for C++ constructor expressions whose range generally
6041 // include the variable declaration, e.g.:
6042 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006043 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00006044 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00006045 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006046 const unsigned I = NextToken();
6047 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
6048 E->getLocStart() == D->getLocation() &&
6049 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006050 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00006051 AdvanceToken();
6052 }
6053 }
6054 }
6055
6056 // Before recursing into the children keep some state that we are going
6057 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
6058 // extra work after the child nodes are visited.
6059 // Note that we don't call VisitChildren here to avoid traversing statements
6060 // code-recursively which can blow the stack.
6061
6062 PostChildrenInfo Info;
6063 Info.Cursor = cursor;
6064 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006065 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006066 Info.BeforeChildrenTokenIdx = NextToken();
6067 PostChildrenInfos.push_back(Info);
6068
6069 return CXChildVisit_Recurse;
6070}
6071
6072bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
6073 if (PostChildrenInfos.empty())
6074 return false;
6075 const PostChildrenInfo &Info = PostChildrenInfos.back();
6076 if (!clang_equalCursors(Info.Cursor, cursor))
6077 return false;
6078
6079 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
6080 const unsigned AfterChildren = NextToken();
6081 SourceRange cursorRange = Info.CursorRange;
6082
6083 // Scan the tokens that are at the end of the cursor, but are not captured
6084 // but the child cursors.
6085 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
6086
6087 // Scan the tokens that are at the beginning of the cursor, but are not
6088 // capture by the child cursors.
6089 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
6090 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
6091 break;
6092
6093 Cursors[I] = cursor;
6094 }
6095
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006096 // Attributes are annotated out-of-order, rewind TokIdx to when we first
6097 // encountered the attribute cursor.
6098 if (clang_isAttribute(cursor.kind))
6099 TokIdx = Info.BeforeReachingCursorIdx;
6100
Guy Benyei11169dd2012-12-18 14:30:41 +00006101 PostChildrenInfos.pop_back();
6102 return false;
6103}
6104
6105static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
6106 CXCursor parent,
6107 CXClientData client_data) {
6108 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
6109}
6110
6111static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
6112 CXClientData client_data) {
6113 return static_cast<AnnotateTokensWorker*>(client_data)->
6114 postVisitChildren(cursor);
6115}
6116
6117namespace {
6118
6119/// \brief Uses the macro expansions in the preprocessing record to find
6120/// and mark tokens that are macro arguments. This info is used by the
6121/// AnnotateTokensWorker.
6122class MarkMacroArgTokensVisitor {
6123 SourceManager &SM;
6124 CXToken *Tokens;
6125 unsigned NumTokens;
6126 unsigned CurIdx;
6127
6128public:
6129 MarkMacroArgTokensVisitor(SourceManager &SM,
6130 CXToken *tokens, unsigned numTokens)
6131 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
6132
6133 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
6134 if (cursor.kind != CXCursor_MacroExpansion)
6135 return CXChildVisit_Continue;
6136
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006137 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00006138 if (macroRange.getBegin() == macroRange.getEnd())
6139 return CXChildVisit_Continue; // it's not a function macro.
6140
6141 for (; CurIdx < NumTokens; ++CurIdx) {
6142 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
6143 macroRange.getBegin()))
6144 break;
6145 }
6146
6147 if (CurIdx == NumTokens)
6148 return CXChildVisit_Break;
6149
6150 for (; CurIdx < NumTokens; ++CurIdx) {
6151 SourceLocation tokLoc = getTokenLoc(CurIdx);
6152 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
6153 break;
6154
6155 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
6156 }
6157
6158 if (CurIdx == NumTokens)
6159 return CXChildVisit_Break;
6160
6161 return CXChildVisit_Continue;
6162 }
6163
6164private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006165 CXToken &getTok(unsigned Idx) {
6166 assert(Idx < NumTokens);
6167 return Tokens[Idx];
6168 }
6169 const CXToken &getTok(unsigned Idx) const {
6170 assert(Idx < NumTokens);
6171 return Tokens[Idx];
6172 }
6173
Guy Benyei11169dd2012-12-18 14:30:41 +00006174 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006175 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006176 }
6177
6178 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
6179 // The third field is reserved and currently not used. Use it here
6180 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006181 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00006182 }
6183};
6184
6185} // end anonymous namespace
6186
6187static CXChildVisitResult
6188MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
6189 CXClientData client_data) {
6190 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
6191 parent);
6192}
6193
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006194/// \brief Used by \c annotatePreprocessorTokens.
6195/// \returns true if lexing was finished, false otherwise.
6196static bool lexNext(Lexer &Lex, Token &Tok,
6197 unsigned &NextIdx, unsigned NumTokens) {
6198 if (NextIdx >= NumTokens)
6199 return true;
6200
6201 ++NextIdx;
6202 Lex.LexFromRawLexer(Tok);
6203 if (Tok.is(tok::eof))
6204 return true;
6205
6206 return false;
6207}
6208
Guy Benyei11169dd2012-12-18 14:30:41 +00006209static void annotatePreprocessorTokens(CXTranslationUnit TU,
6210 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006211 CXCursor *Cursors,
6212 CXToken *Tokens,
6213 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006214 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006215
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006216 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00006217 SourceManager &SourceMgr = CXXUnit->getSourceManager();
6218 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006219 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00006220 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006221 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00006222
6223 if (BeginLocInfo.first != EndLocInfo.first)
6224 return;
6225
6226 StringRef Buffer;
6227 bool Invalid = false;
6228 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
6229 if (Buffer.empty() || Invalid)
6230 return;
6231
6232 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
6233 CXXUnit->getASTContext().getLangOpts(),
6234 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
6235 Buffer.end());
6236 Lex.SetCommentRetentionState(true);
6237
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006238 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006239 // Lex tokens in raw mode until we hit the end of the range, to avoid
6240 // entering #includes or expanding macros.
6241 while (true) {
6242 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006243 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6244 break;
6245 unsigned TokIdx = NextIdx-1;
6246 assert(Tok.getLocation() ==
6247 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006248
6249 reprocess:
6250 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006251 // We have found a preprocessing directive. Annotate the tokens
6252 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00006253 //
6254 // FIXME: Some simple tests here could identify macro definitions and
6255 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006256
6257 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006258 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6259 break;
6260
Craig Topper69186e72014-06-08 08:38:04 +00006261 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00006262 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006263 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6264 break;
6265
6266 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00006267 IdentifierInfo &II =
6268 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006269 SourceLocation MappedTokLoc =
6270 CXXUnit->mapLocationToPreamble(Tok.getLocation());
6271 MI = getMacroInfo(II, MappedTokLoc, TU);
6272 }
6273 }
6274
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006275 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00006276 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006277 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
6278 finished = true;
6279 break;
6280 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006281 // If we are in a macro definition, check if the token was ever a
6282 // macro name and annotate it if that's the case.
6283 if (MI) {
6284 SourceLocation SaveLoc = Tok.getLocation();
6285 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
Richard Smith66a81862015-05-04 02:25:31 +00006286 MacroDefinitionRecord *MacroDef =
6287 checkForMacroInMacroDefinition(MI, Tok, TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006288 Tok.setLocation(SaveLoc);
6289 if (MacroDef)
Richard Smith66a81862015-05-04 02:25:31 +00006290 Cursors[NextIdx - 1] =
6291 MakeMacroExpansionCursor(MacroDef, Tok.getLocation(), TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006292 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006293 } while (!Tok.isAtStartOfLine());
6294
6295 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
6296 assert(TokIdx <= LastIdx);
6297 SourceLocation EndLoc =
6298 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
6299 CXCursor Cursor =
6300 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
6301
6302 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006303 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006304
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006305 if (finished)
6306 break;
6307 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00006308 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006309 }
6310}
6311
6312// This gets run a separate thread to avoid stack blowout.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006313static void clang_annotateTokensImpl(CXTranslationUnit TU, ASTUnit *CXXUnit,
6314 CXToken *Tokens, unsigned NumTokens,
6315 CXCursor *Cursors) {
Dmitri Gribenko183436e2013-01-26 21:49:50 +00006316 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006317 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
6318 setThreadBackgroundPriority();
6319
6320 // Determine the region of interest, which contains all of the tokens.
6321 SourceRange RegionOfInterest;
6322 RegionOfInterest.setBegin(
6323 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
6324 RegionOfInterest.setEnd(
6325 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
6326 Tokens[NumTokens-1])));
6327
Guy Benyei11169dd2012-12-18 14:30:41 +00006328 // Relex the tokens within the source range to look for preprocessing
6329 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006330 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006331
6332 // If begin location points inside a macro argument, set it to the expansion
6333 // location so we can have the full context when annotating semantically.
6334 {
6335 SourceManager &SM = CXXUnit->getSourceManager();
6336 SourceLocation Loc =
6337 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
6338 if (Loc.isMacroID())
6339 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
6340 }
6341
Guy Benyei11169dd2012-12-18 14:30:41 +00006342 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
6343 // Search and mark tokens that are macro argument expansions.
6344 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
6345 Tokens, NumTokens);
6346 CursorVisitor MacroArgMarker(TU,
6347 MarkMacroArgTokensVisitorDelegate, &Visitor,
6348 /*VisitPreprocessorLast=*/true,
6349 /*VisitIncludedEntities=*/false,
6350 RegionOfInterest);
6351 MacroArgMarker.visitPreprocessedEntitiesInRegion();
6352 }
6353
6354 // Annotate all of the source locations in the region of interest that map to
6355 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006356 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00006357
6358 // FIXME: We use a ridiculous stack size here because the data-recursion
6359 // algorithm uses a large stack frame than the non-data recursive version,
6360 // and AnnotationTokensWorker currently transforms the data-recursion
6361 // algorithm back into a traditional recursion by explicitly calling
6362 // VisitChildren(). We will need to remove this explicit recursive call.
6363 W.AnnotateTokens();
6364
6365 // If we ran into any entities that involve context-sensitive keywords,
6366 // take another pass through the tokens to mark them as such.
6367 if (W.hasContextSensitiveKeywords()) {
6368 for (unsigned I = 0; I != NumTokens; ++I) {
6369 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
6370 continue;
6371
6372 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
6373 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006374 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006375 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
6376 if (Property->getPropertyAttributesAsWritten() != 0 &&
6377 llvm::StringSwitch<bool>(II->getName())
6378 .Case("readonly", true)
6379 .Case("assign", true)
6380 .Case("unsafe_unretained", true)
6381 .Case("readwrite", true)
6382 .Case("retain", true)
6383 .Case("copy", true)
6384 .Case("nonatomic", true)
6385 .Case("atomic", true)
6386 .Case("getter", true)
6387 .Case("setter", true)
6388 .Case("strong", true)
6389 .Case("weak", true)
6390 .Default(false))
6391 Tokens[I].int_data[0] = CXToken_Keyword;
6392 }
6393 continue;
6394 }
6395
6396 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6397 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6398 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6399 if (llvm::StringSwitch<bool>(II->getName())
6400 .Case("in", true)
6401 .Case("out", true)
6402 .Case("inout", true)
6403 .Case("oneway", true)
6404 .Case("bycopy", true)
6405 .Case("byref", true)
6406 .Default(false))
6407 Tokens[I].int_data[0] = CXToken_Keyword;
6408 continue;
6409 }
6410
6411 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6412 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6413 Tokens[I].int_data[0] = CXToken_Keyword;
6414 continue;
6415 }
6416 }
6417 }
6418}
6419
6420extern "C" {
6421
6422void clang_annotateTokens(CXTranslationUnit TU,
6423 CXToken *Tokens, unsigned NumTokens,
6424 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006425 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006426 LOG_BAD_TU(TU);
6427 return;
6428 }
6429 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006430 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006431 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006432 }
6433
6434 LOG_FUNC_SECTION {
6435 *Log << TU << ' ';
6436 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6437 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6438 *Log << clang_getRange(bloc, eloc);
6439 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006440
6441 // Any token we don't specifically annotate will have a NULL cursor.
6442 CXCursor C = clang_getNullCursor();
6443 for (unsigned I = 0; I != NumTokens; ++I)
6444 Cursors[I] = C;
6445
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006446 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006447 if (!CXXUnit)
6448 return;
6449
6450 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006451
6452 auto AnnotateTokensImpl = [=]() {
6453 clang_annotateTokensImpl(TU, CXXUnit, Tokens, NumTokens, Cursors);
6454 };
Guy Benyei11169dd2012-12-18 14:30:41 +00006455 llvm::CrashRecoveryContext CRC;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006456 if (!RunSafely(CRC, AnnotateTokensImpl, GetSafetyThreadStackSize() * 2)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006457 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6458 }
6459}
6460
6461} // end: extern "C"
6462
6463//===----------------------------------------------------------------------===//
6464// Operations for querying linkage of a cursor.
6465//===----------------------------------------------------------------------===//
6466
6467extern "C" {
6468CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6469 if (!clang_isDeclaration(cursor.kind))
6470 return CXLinkage_Invalid;
6471
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006472 const Decl *D = cxcursor::getCursorDecl(cursor);
6473 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006474 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006475 case NoLinkage:
6476 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006477 case InternalLinkage: return CXLinkage_Internal;
6478 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6479 case ExternalLinkage: return CXLinkage_External;
6480 };
6481
6482 return CXLinkage_Invalid;
6483}
6484} // end: extern "C"
6485
6486//===----------------------------------------------------------------------===//
Ehsan Akhgari93697fa2015-11-23 19:56:46 +00006487// Operations for querying visibility of a cursor.
6488//===----------------------------------------------------------------------===//
6489
6490extern "C" {
6491CXVisibilityKind clang_getCursorVisibility(CXCursor cursor) {
6492 if (!clang_isDeclaration(cursor.kind))
6493 return CXVisibility_Invalid;
6494
6495 const Decl *D = cxcursor::getCursorDecl(cursor);
6496 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
6497 switch (ND->getVisibility()) {
6498 case HiddenVisibility: return CXVisibility_Hidden;
6499 case ProtectedVisibility: return CXVisibility_Protected;
6500 case DefaultVisibility: return CXVisibility_Default;
6501 };
6502
6503 return CXVisibility_Invalid;
6504}
6505} // end: extern "C"
6506
6507//===----------------------------------------------------------------------===//
Guy Benyei11169dd2012-12-18 14:30:41 +00006508// Operations for querying language of a cursor.
6509//===----------------------------------------------------------------------===//
6510
6511static CXLanguageKind getDeclLanguage(const Decl *D) {
6512 if (!D)
6513 return CXLanguage_C;
6514
6515 switch (D->getKind()) {
6516 default:
6517 break;
6518 case Decl::ImplicitParam:
6519 case Decl::ObjCAtDefsField:
6520 case Decl::ObjCCategory:
6521 case Decl::ObjCCategoryImpl:
6522 case Decl::ObjCCompatibleAlias:
6523 case Decl::ObjCImplementation:
6524 case Decl::ObjCInterface:
6525 case Decl::ObjCIvar:
6526 case Decl::ObjCMethod:
6527 case Decl::ObjCProperty:
6528 case Decl::ObjCPropertyImpl:
6529 case Decl::ObjCProtocol:
Douglas Gregor85f3f952015-07-07 03:57:15 +00006530 case Decl::ObjCTypeParam:
Guy Benyei11169dd2012-12-18 14:30:41 +00006531 return CXLanguage_ObjC;
6532 case Decl::CXXConstructor:
6533 case Decl::CXXConversion:
6534 case Decl::CXXDestructor:
6535 case Decl::CXXMethod:
6536 case Decl::CXXRecord:
6537 case Decl::ClassTemplate:
6538 case Decl::ClassTemplatePartialSpecialization:
6539 case Decl::ClassTemplateSpecialization:
6540 case Decl::Friend:
6541 case Decl::FriendTemplate:
6542 case Decl::FunctionTemplate:
6543 case Decl::LinkageSpec:
6544 case Decl::Namespace:
6545 case Decl::NamespaceAlias:
6546 case Decl::NonTypeTemplateParm:
6547 case Decl::StaticAssert:
6548 case Decl::TemplateTemplateParm:
6549 case Decl::TemplateTypeParm:
6550 case Decl::UnresolvedUsingTypename:
6551 case Decl::UnresolvedUsingValue:
6552 case Decl::Using:
6553 case Decl::UsingDirective:
6554 case Decl::UsingShadow:
6555 return CXLanguage_CPlusPlus;
6556 }
6557
6558 return CXLanguage_C;
6559}
6560
6561extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006562
6563static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6564 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
Manuel Klimek8e3a7ed2015-09-25 17:53:16 +00006565 return CXAvailability_NotAvailable;
Guy Benyei11169dd2012-12-18 14:30:41 +00006566
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006567 switch (D->getAvailability()) {
6568 case AR_Available:
6569 case AR_NotYetIntroduced:
6570 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006571 return getCursorAvailabilityForDecl(
6572 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006573 return CXAvailability_Available;
6574
6575 case AR_Deprecated:
6576 return CXAvailability_Deprecated;
6577
6578 case AR_Unavailable:
6579 return CXAvailability_NotAvailable;
6580 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006581
6582 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006583}
6584
Guy Benyei11169dd2012-12-18 14:30:41 +00006585enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6586 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006587 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6588 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006589
6590 return CXAvailability_Available;
6591}
6592
6593static CXVersion convertVersion(VersionTuple In) {
6594 CXVersion Out = { -1, -1, -1 };
6595 if (In.empty())
6596 return Out;
6597
6598 Out.Major = In.getMajor();
6599
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006600 Optional<unsigned> Minor = In.getMinor();
6601 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006602 Out.Minor = *Minor;
6603 else
6604 return Out;
6605
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006606 Optional<unsigned> Subminor = In.getSubminor();
6607 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006608 Out.Subminor = *Subminor;
6609
6610 return Out;
6611}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006612
6613static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6614 int *always_deprecated,
6615 CXString *deprecated_message,
6616 int *always_unavailable,
6617 CXString *unavailable_message,
6618 CXPlatformAvailability *availability,
6619 int availability_size) {
6620 bool HadAvailAttr = false;
6621 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006622 for (auto A : D->attrs()) {
6623 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006624 HadAvailAttr = true;
6625 if (always_deprecated)
6626 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006627 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006628 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006629 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006630 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006631 continue;
6632 }
6633
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006634 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006635 HadAvailAttr = true;
6636 if (always_unavailable)
6637 *always_unavailable = 1;
6638 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006639 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006640 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6641 }
6642 continue;
6643 }
6644
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006645 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006646 HadAvailAttr = true;
6647 if (N < availability_size) {
6648 availability[N].Platform
6649 = cxstring::createDup(Avail->getPlatform()->getName());
6650 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6651 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6652 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6653 availability[N].Unavailable = Avail->getUnavailable();
6654 availability[N].Message = cxstring::createDup(Avail->getMessage());
6655 }
6656 ++N;
6657 }
6658 }
6659
6660 if (!HadAvailAttr)
6661 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6662 return getCursorPlatformAvailabilityForDecl(
6663 cast<Decl>(EnumConst->getDeclContext()),
6664 always_deprecated,
6665 deprecated_message,
6666 always_unavailable,
6667 unavailable_message,
6668 availability,
6669 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006670
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006671 return N;
6672}
6673
Guy Benyei11169dd2012-12-18 14:30:41 +00006674int clang_getCursorPlatformAvailability(CXCursor cursor,
6675 int *always_deprecated,
6676 CXString *deprecated_message,
6677 int *always_unavailable,
6678 CXString *unavailable_message,
6679 CXPlatformAvailability *availability,
6680 int availability_size) {
6681 if (always_deprecated)
6682 *always_deprecated = 0;
6683 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006684 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006685 if (always_unavailable)
6686 *always_unavailable = 0;
6687 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006688 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006689
Guy Benyei11169dd2012-12-18 14:30:41 +00006690 if (!clang_isDeclaration(cursor.kind))
6691 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006692
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006693 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006694 if (!D)
6695 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006696
6697 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6698 deprecated_message,
6699 always_unavailable,
6700 unavailable_message,
6701 availability,
6702 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006703}
6704
6705void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6706 clang_disposeString(availability->Platform);
6707 clang_disposeString(availability->Message);
6708}
6709
6710CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6711 if (clang_isDeclaration(cursor.kind))
6712 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6713
6714 return CXLanguage_Invalid;
6715}
6716
6717 /// \brief If the given cursor is the "templated" declaration
6718 /// descibing a class or function template, return the class or
6719 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006720static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006721 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006722 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006723
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006724 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006725 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6726 return FunTmpl;
6727
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006728 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006729 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6730 return ClassTmpl;
6731
6732 return D;
6733}
6734
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006735
6736enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
6737 StorageClass sc = SC_None;
6738 const Decl *D = getCursorDecl(C);
6739 if (D) {
6740 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
6741 sc = FD->getStorageClass();
6742 } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
6743 sc = VD->getStorageClass();
6744 } else {
6745 return CX_SC_Invalid;
6746 }
6747 } else {
6748 return CX_SC_Invalid;
6749 }
6750 switch (sc) {
6751 case SC_None:
6752 return CX_SC_None;
6753 case SC_Extern:
6754 return CX_SC_Extern;
6755 case SC_Static:
6756 return CX_SC_Static;
6757 case SC_PrivateExtern:
6758 return CX_SC_PrivateExtern;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006759 case SC_Auto:
6760 return CX_SC_Auto;
6761 case SC_Register:
6762 return CX_SC_Register;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006763 }
Kaelyn Takataab61e702014-10-15 18:03:26 +00006764 llvm_unreachable("Unhandled storage class!");
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006765}
6766
Guy Benyei11169dd2012-12-18 14:30:41 +00006767CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6768 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006769 if (const Decl *D = getCursorDecl(cursor)) {
6770 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006771 if (!DC)
6772 return clang_getNullCursor();
6773
6774 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6775 getCursorTU(cursor));
6776 }
6777 }
6778
6779 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006780 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006781 return MakeCXCursor(D, getCursorTU(cursor));
6782 }
6783
6784 return clang_getNullCursor();
6785}
6786
6787CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6788 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006789 if (const Decl *D = getCursorDecl(cursor)) {
6790 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006791 if (!DC)
6792 return clang_getNullCursor();
6793
6794 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6795 getCursorTU(cursor));
6796 }
6797 }
6798
6799 // FIXME: Note that we can't easily compute the lexical context of a
6800 // statement or expression, so we return nothing.
6801 return clang_getNullCursor();
6802}
6803
6804CXFile clang_getIncludedFile(CXCursor cursor) {
6805 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006806 return nullptr;
6807
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006808 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006809 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006810}
6811
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006812unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6813 if (C.kind != CXCursor_ObjCPropertyDecl)
6814 return CXObjCPropertyAttr_noattr;
6815
6816 unsigned Result = CXObjCPropertyAttr_noattr;
6817 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6818 ObjCPropertyDecl::PropertyAttributeKind Attr =
6819 PD->getPropertyAttributesAsWritten();
6820
6821#define SET_CXOBJCPROP_ATTR(A) \
6822 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6823 Result |= CXObjCPropertyAttr_##A
6824 SET_CXOBJCPROP_ATTR(readonly);
6825 SET_CXOBJCPROP_ATTR(getter);
6826 SET_CXOBJCPROP_ATTR(assign);
6827 SET_CXOBJCPROP_ATTR(readwrite);
6828 SET_CXOBJCPROP_ATTR(retain);
6829 SET_CXOBJCPROP_ATTR(copy);
6830 SET_CXOBJCPROP_ATTR(nonatomic);
6831 SET_CXOBJCPROP_ATTR(setter);
6832 SET_CXOBJCPROP_ATTR(atomic);
6833 SET_CXOBJCPROP_ATTR(weak);
6834 SET_CXOBJCPROP_ATTR(strong);
6835 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6836#undef SET_CXOBJCPROP_ATTR
6837
6838 return Result;
6839}
6840
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006841unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6842 if (!clang_isDeclaration(C.kind))
6843 return CXObjCDeclQualifier_None;
6844
6845 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6846 const Decl *D = getCursorDecl(C);
6847 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6848 QT = MD->getObjCDeclQualifier();
6849 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6850 QT = PD->getObjCDeclQualifier();
6851 if (QT == Decl::OBJC_TQ_None)
6852 return CXObjCDeclQualifier_None;
6853
6854 unsigned Result = CXObjCDeclQualifier_None;
6855 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6856 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6857 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6858 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6859 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6860 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6861
6862 return Result;
6863}
6864
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006865unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6866 if (!clang_isDeclaration(C.kind))
6867 return 0;
6868
6869 const Decl *D = getCursorDecl(C);
6870 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6871 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6872 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6873 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6874
6875 return 0;
6876}
6877
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006878unsigned clang_Cursor_isVariadic(CXCursor C) {
6879 if (!clang_isDeclaration(C.kind))
6880 return 0;
6881
6882 const Decl *D = getCursorDecl(C);
6883 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6884 return FD->isVariadic();
6885 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6886 return MD->isVariadic();
6887
6888 return 0;
6889}
6890
Guy Benyei11169dd2012-12-18 14:30:41 +00006891CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6892 if (!clang_isDeclaration(C.kind))
6893 return clang_getNullRange();
6894
6895 const Decl *D = getCursorDecl(C);
6896 ASTContext &Context = getCursorContext(C);
6897 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6898 if (!RC)
6899 return clang_getNullRange();
6900
6901 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6902}
6903
6904CXString clang_Cursor_getRawCommentText(CXCursor C) {
6905 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006906 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006907
6908 const Decl *D = getCursorDecl(C);
6909 ASTContext &Context = getCursorContext(C);
6910 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6911 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6912 StringRef();
6913
6914 // Don't duplicate the string because RawText points directly into source
6915 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006916 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006917}
6918
6919CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6920 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006921 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006922
6923 const Decl *D = getCursorDecl(C);
6924 const ASTContext &Context = getCursorContext(C);
6925 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6926
6927 if (RC) {
6928 StringRef BriefText = RC->getBriefText(Context);
6929
6930 // Don't duplicate the string because RawComment ensures that this memory
6931 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006932 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006933 }
6934
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006935 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006936}
6937
Guy Benyei11169dd2012-12-18 14:30:41 +00006938CXModule clang_Cursor_getModule(CXCursor C) {
6939 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006940 if (const ImportDecl *ImportD =
6941 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006942 return ImportD->getImportedModule();
6943 }
6944
Craig Topper69186e72014-06-08 08:38:04 +00006945 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006946}
6947
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006948CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6949 if (isNotUsableTU(TU)) {
6950 LOG_BAD_TU(TU);
6951 return nullptr;
6952 }
6953 if (!File)
6954 return nullptr;
6955 FileEntry *FE = static_cast<FileEntry *>(File);
6956
6957 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6958 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6959 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6960
Richard Smithfeb54b62014-10-23 02:01:19 +00006961 return Header.getModule();
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006962}
6963
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006964CXFile clang_Module_getASTFile(CXModule CXMod) {
6965 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006966 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006967 Module *Mod = static_cast<Module*>(CXMod);
6968 return const_cast<FileEntry *>(Mod->getASTFile());
6969}
6970
Guy Benyei11169dd2012-12-18 14:30:41 +00006971CXModule clang_Module_getParent(CXModule CXMod) {
6972 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006973 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006974 Module *Mod = static_cast<Module*>(CXMod);
6975 return Mod->Parent;
6976}
6977
6978CXString clang_Module_getName(CXModule CXMod) {
6979 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006980 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006981 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006982 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006983}
6984
6985CXString clang_Module_getFullName(CXModule CXMod) {
6986 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006987 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006988 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006989 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006990}
6991
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006992int clang_Module_isSystem(CXModule CXMod) {
6993 if (!CXMod)
6994 return 0;
6995 Module *Mod = static_cast<Module*>(CXMod);
6996 return Mod->IsSystem;
6997}
6998
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006999unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
7000 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007001 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007002 LOG_BAD_TU(TU);
7003 return 0;
7004 }
7005 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00007006 return 0;
7007 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007008 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
7009 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
7010 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00007011}
7012
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007013CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
7014 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007015 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007016 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00007017 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007018 }
7019 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00007020 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007021 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007022 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00007023
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007024 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
7025 if (Index < TopHeaders.size())
7026 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00007027
Craig Topper69186e72014-06-08 08:38:04 +00007028 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007029}
7030
7031} // end: extern "C"
7032
7033//===----------------------------------------------------------------------===//
7034// C++ AST instrospection.
7035//===----------------------------------------------------------------------===//
7036
7037extern "C" {
Saleem Abdulrasool6ea75db2015-10-27 15:50:22 +00007038unsigned clang_CXXField_isMutable(CXCursor C) {
7039 if (!clang_isDeclaration(C.kind))
7040 return 0;
7041
7042 if (const auto D = cxcursor::getCursorDecl(C))
7043 if (const auto FD = dyn_cast_or_null<FieldDecl>(D))
7044 return FD->isMutable() ? 1 : 0;
7045 return 0;
7046}
7047
Dmitri Gribenko62770be2013-05-17 18:38:35 +00007048unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
7049 if (!clang_isDeclaration(C.kind))
7050 return 0;
7051
Dmitri Gribenko62770be2013-05-17 18:38:35 +00007052 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007053 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007054 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00007055 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
7056}
7057
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00007058unsigned clang_CXXMethod_isConst(CXCursor C) {
7059 if (!clang_isDeclaration(C.kind))
7060 return 0;
7061
7062 const Decl *D = cxcursor::getCursorDecl(C);
7063 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007064 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00007065 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
7066}
7067
Guy Benyei11169dd2012-12-18 14:30:41 +00007068unsigned clang_CXXMethod_isStatic(CXCursor C) {
7069 if (!clang_isDeclaration(C.kind))
7070 return 0;
7071
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007072 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007073 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007074 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007075 return (Method && Method->isStatic()) ? 1 : 0;
7076}
7077
7078unsigned clang_CXXMethod_isVirtual(CXCursor C) {
7079 if (!clang_isDeclaration(C.kind))
7080 return 0;
7081
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007082 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007083 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007084 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007085 return (Method && Method->isVirtual()) ? 1 : 0;
7086}
7087} // end: extern "C"
7088
7089//===----------------------------------------------------------------------===//
7090// Attribute introspection.
7091//===----------------------------------------------------------------------===//
7092
7093extern "C" {
7094CXType clang_getIBOutletCollectionType(CXCursor C) {
7095 if (C.kind != CXCursor_IBOutletCollectionAttr)
7096 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
7097
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00007098 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00007099 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
7100
7101 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
7102}
7103} // end: extern "C"
7104
7105//===----------------------------------------------------------------------===//
7106// Inspecting memory usage.
7107//===----------------------------------------------------------------------===//
7108
7109typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
7110
7111static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
7112 enum CXTUResourceUsageKind k,
7113 unsigned long amount) {
7114 CXTUResourceUsageEntry entry = { k, amount };
7115 entries.push_back(entry);
7116}
7117
7118extern "C" {
7119
7120const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
7121 const char *str = "";
7122 switch (kind) {
7123 case CXTUResourceUsage_AST:
7124 str = "ASTContext: expressions, declarations, and types";
7125 break;
7126 case CXTUResourceUsage_Identifiers:
7127 str = "ASTContext: identifiers";
7128 break;
7129 case CXTUResourceUsage_Selectors:
7130 str = "ASTContext: selectors";
7131 break;
7132 case CXTUResourceUsage_GlobalCompletionResults:
7133 str = "Code completion: cached global results";
7134 break;
7135 case CXTUResourceUsage_SourceManagerContentCache:
7136 str = "SourceManager: content cache allocator";
7137 break;
7138 case CXTUResourceUsage_AST_SideTables:
7139 str = "ASTContext: side tables";
7140 break;
7141 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
7142 str = "SourceManager: malloc'ed memory buffers";
7143 break;
7144 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
7145 str = "SourceManager: mmap'ed memory buffers";
7146 break;
7147 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
7148 str = "ExternalASTSource: malloc'ed memory buffers";
7149 break;
7150 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
7151 str = "ExternalASTSource: mmap'ed memory buffers";
7152 break;
7153 case CXTUResourceUsage_Preprocessor:
7154 str = "Preprocessor: malloc'ed memory";
7155 break;
7156 case CXTUResourceUsage_PreprocessingRecord:
7157 str = "Preprocessor: PreprocessingRecord";
7158 break;
7159 case CXTUResourceUsage_SourceManager_DataStructures:
7160 str = "SourceManager: data structures and tables";
7161 break;
7162 case CXTUResourceUsage_Preprocessor_HeaderSearch:
7163 str = "Preprocessor: header search tables";
7164 break;
7165 }
7166 return str;
7167}
7168
7169CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007170 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007171 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00007172 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00007173 return usage;
7174 }
7175
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007176 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00007177 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00007178 ASTContext &astContext = astUnit->getASTContext();
7179
7180 // How much memory is used by AST nodes and types?
7181 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
7182 (unsigned long) astContext.getASTAllocatedMemory());
7183
7184 // How much memory is used by identifiers?
7185 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
7186 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
7187
7188 // How much memory is used for selectors?
7189 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
7190 (unsigned long) astContext.Selectors.getTotalMemory());
7191
7192 // How much memory is used by ASTContext's side tables?
7193 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
7194 (unsigned long) astContext.getSideTableAllocatedMemory());
7195
7196 // How much memory is used for caching global code completion results?
7197 unsigned long completionBytes = 0;
7198 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00007199 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007200 completionBytes = completionAllocator->getTotalMemory();
7201 }
7202 createCXTUResourceUsageEntry(*entries,
7203 CXTUResourceUsage_GlobalCompletionResults,
7204 completionBytes);
7205
7206 // How much memory is being used by SourceManager's content cache?
7207 createCXTUResourceUsageEntry(*entries,
7208 CXTUResourceUsage_SourceManagerContentCache,
7209 (unsigned long) astContext.getSourceManager().getContentCacheSize());
7210
7211 // How much memory is being used by the MemoryBuffer's in SourceManager?
7212 const SourceManager::MemoryBufferSizes &srcBufs =
7213 astUnit->getSourceManager().getMemoryBufferSizes();
7214
7215 createCXTUResourceUsageEntry(*entries,
7216 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
7217 (unsigned long) srcBufs.malloc_bytes);
7218 createCXTUResourceUsageEntry(*entries,
7219 CXTUResourceUsage_SourceManager_Membuffer_MMap,
7220 (unsigned long) srcBufs.mmap_bytes);
7221 createCXTUResourceUsageEntry(*entries,
7222 CXTUResourceUsage_SourceManager_DataStructures,
7223 (unsigned long) astContext.getSourceManager()
7224 .getDataStructureSizes());
7225
7226 // How much memory is being used by the ExternalASTSource?
7227 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
7228 const ExternalASTSource::MemoryBufferSizes &sizes =
7229 esrc->getMemoryBufferSizes();
7230
7231 createCXTUResourceUsageEntry(*entries,
7232 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
7233 (unsigned long) sizes.malloc_bytes);
7234 createCXTUResourceUsageEntry(*entries,
7235 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
7236 (unsigned long) sizes.mmap_bytes);
7237 }
7238
7239 // How much memory is being used by the Preprocessor?
7240 Preprocessor &pp = astUnit->getPreprocessor();
7241 createCXTUResourceUsageEntry(*entries,
7242 CXTUResourceUsage_Preprocessor,
7243 pp.getTotalMemory());
7244
7245 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
7246 createCXTUResourceUsageEntry(*entries,
7247 CXTUResourceUsage_PreprocessingRecord,
7248 pRec->getTotalMemory());
7249 }
7250
7251 createCXTUResourceUsageEntry(*entries,
7252 CXTUResourceUsage_Preprocessor_HeaderSearch,
7253 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00007254
Guy Benyei11169dd2012-12-18 14:30:41 +00007255 CXTUResourceUsage usage = { (void*) entries.get(),
7256 (unsigned) entries->size(),
Alexander Kornienko6ee521c2015-01-23 15:36:10 +00007257 !entries->empty() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00007258 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00007259 return usage;
7260}
7261
7262void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
7263 if (usage.data)
7264 delete (MemUsageEntries*) usage.data;
7265}
7266
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007267CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
7268 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007269 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00007270 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007271
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007272 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007273 LOG_BAD_TU(TU);
7274 return skipped;
7275 }
7276
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007277 if (!file)
7278 return skipped;
7279
7280 ASTUnit *astUnit = cxtu::getASTUnit(TU);
7281 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
7282 if (!ppRec)
7283 return skipped;
7284
7285 ASTContext &Ctx = astUnit->getASTContext();
7286 SourceManager &sm = Ctx.getSourceManager();
7287 FileEntry *fileEntry = static_cast<FileEntry *>(file);
7288 FileID wantedFileID = sm.translateFile(fileEntry);
7289
7290 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
7291 std::vector<SourceRange> wantedRanges;
7292 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
7293 i != ei; ++i) {
7294 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
7295 wantedRanges.push_back(*i);
7296 }
7297
7298 skipped->count = wantedRanges.size();
7299 skipped->ranges = new CXSourceRange[skipped->count];
7300 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
7301 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
7302
7303 return skipped;
7304}
7305
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007306void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
7307 if (ranges) {
7308 delete[] ranges->ranges;
7309 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007310 }
7311}
7312
Guy Benyei11169dd2012-12-18 14:30:41 +00007313} // end extern "C"
7314
7315void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
7316 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
7317 for (unsigned I = 0; I != Usage.numEntries; ++I)
7318 fprintf(stderr, " %s: %lu\n",
7319 clang_getTUResourceUsageName(Usage.entries[I].kind),
7320 Usage.entries[I].amount);
7321
7322 clang_disposeCXTUResourceUsage(Usage);
7323}
7324
7325//===----------------------------------------------------------------------===//
7326// Misc. utility functions.
7327//===----------------------------------------------------------------------===//
7328
7329/// Default to using an 8 MB stack size on "safety" threads.
7330static unsigned SafetyStackThreadSize = 8 << 20;
7331
7332namespace clang {
7333
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007334bool RunSafely(llvm::CrashRecoveryContext &CRC, llvm::function_ref<void()> Fn,
Guy Benyei11169dd2012-12-18 14:30:41 +00007335 unsigned Size) {
7336 if (!Size)
7337 Size = GetSafetyThreadStackSize();
7338 if (Size)
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007339 return CRC.RunSafelyOnThread(Fn, Size);
7340 return CRC.RunSafely(Fn);
Guy Benyei11169dd2012-12-18 14:30:41 +00007341}
7342
7343unsigned GetSafetyThreadStackSize() {
7344 return SafetyStackThreadSize;
7345}
7346
7347void SetSafetyThreadStackSize(unsigned Value) {
7348 SafetyStackThreadSize = Value;
7349}
7350
Alexander Kornienkoab9db512015-06-22 23:07:51 +00007351}
Guy Benyei11169dd2012-12-18 14:30:41 +00007352
7353void clang::setThreadBackgroundPriority() {
7354 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
7355 return;
7356
Alp Toker1a86ad22014-07-06 06:24:00 +00007357#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00007358 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
7359#endif
7360}
7361
7362void cxindex::printDiagsToStderr(ASTUnit *Unit) {
7363 if (!Unit)
7364 return;
7365
7366 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
7367 DEnd = Unit->stored_diag_end();
7368 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00007369 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00007370 CXString Msg = clang_formatDiagnostic(&Diag,
7371 clang_defaultDiagnosticDisplayOptions());
7372 fprintf(stderr, "%s\n", clang_getCString(Msg));
7373 clang_disposeString(Msg);
7374 }
7375#ifdef LLVM_ON_WIN32
7376 // On Windows, force a flush, since there may be multiple copies of
7377 // stderr and stdout in the file system, all with different buffers
7378 // but writing to the same device.
7379 fflush(stderr);
7380#endif
7381}
7382
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007383MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
7384 SourceLocation MacroDefLoc,
7385 CXTranslationUnit TU){
7386 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007387 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007388 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007389 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007390
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007391 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007392 Preprocessor &PP = Unit->getPreprocessor();
Richard Smith20e883e2015-04-29 23:20:19 +00007393 MacroDirective *MD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007394 if (MD) {
7395 for (MacroDirective::DefInfo
7396 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
7397 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
7398 return Def.getMacroInfo();
7399 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007400 }
7401
Craig Topper69186e72014-06-08 08:38:04 +00007402 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007403}
7404
Richard Smith66a81862015-05-04 02:25:31 +00007405const MacroInfo *cxindex::getMacroInfo(const MacroDefinitionRecord *MacroDef,
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007406 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007407 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007408 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007409 const IdentifierInfo *II = MacroDef->getName();
7410 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00007411 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007412
7413 return getMacroInfo(*II, MacroDef->getLocation(), TU);
7414}
7415
Richard Smith66a81862015-05-04 02:25:31 +00007416MacroDefinitionRecord *
7417cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, const Token &Tok,
7418 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007419 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007420 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007421 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00007422 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007423
7424 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007425 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007426 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
7427 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007428 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007429
7430 // Check that the token is inside the definition and not its argument list.
7431 SourceManager &SM = Unit->getSourceManager();
7432 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00007433 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007434 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00007435 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007436
7437 Preprocessor &PP = Unit->getPreprocessor();
7438 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
7439 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00007440 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007441
Alp Toker2d57cea2014-05-17 04:53:25 +00007442 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007443 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007444 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007445
7446 // Check that the identifier is not one of the macro arguments.
7447 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00007448 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007449
Richard Smith20e883e2015-04-29 23:20:19 +00007450 MacroDirective *InnerMD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007451 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00007452 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007453
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007454 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007455}
7456
Richard Smith66a81862015-05-04 02:25:31 +00007457MacroDefinitionRecord *
7458cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, SourceLocation Loc,
7459 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007460 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007461 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007462
7463 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007464 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007465 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007466 Preprocessor &PP = Unit->getPreprocessor();
7467 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00007468 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007469 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7470 Token Tok;
7471 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00007472 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007473
7474 return checkForMacroInMacroDefinition(MI, Tok, TU);
7475}
7476
Guy Benyei11169dd2012-12-18 14:30:41 +00007477extern "C" {
7478
7479CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007480 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00007481}
7482
7483} // end: extern "C"
7484
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007485Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7486 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007487 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007488 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007489 if (Unit->isMainFileAST())
7490 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007491 return *this;
7492 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007493 } else {
7494 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007495 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007496 return *this;
7497}
7498
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007499Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7500 *this << FE->getName();
7501 return *this;
7502}
7503
7504Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7505 CXString cursorName = clang_getCursorDisplayName(cursor);
7506 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7507 clang_disposeString(cursorName);
7508 return *this;
7509}
7510
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007511Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7512 CXFile File;
7513 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007514 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007515 CXString FileName = clang_getFileName(File);
7516 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7517 clang_disposeString(FileName);
7518 return *this;
7519}
7520
7521Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7522 CXSourceLocation BLoc = clang_getRangeStart(range);
7523 CXSourceLocation ELoc = clang_getRangeEnd(range);
7524
7525 CXFile BFile;
7526 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007527 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007528
7529 CXFile EFile;
7530 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007531 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007532
7533 CXString BFileName = clang_getFileName(BFile);
7534 if (BFile == EFile) {
7535 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7536 BLine, BColumn, ELine, EColumn);
7537 } else {
7538 CXString EFileName = clang_getFileName(EFile);
7539 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7540 BLine, BColumn)
7541 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7542 ELine, EColumn);
7543 clang_disposeString(EFileName);
7544 }
7545 clang_disposeString(BFileName);
7546 return *this;
7547}
7548
7549Logger &cxindex::Logger::operator<<(CXString Str) {
7550 *this << clang_getCString(Str);
7551 return *this;
7552}
7553
7554Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7555 LogOS << Fmt;
7556 return *this;
7557}
7558
Chandler Carruth37ad2582014-06-27 15:14:39 +00007559static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7560
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007561cxindex::Logger::~Logger() {
Chandler Carruth37ad2582014-06-27 15:14:39 +00007562 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007563
7564 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7565
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007566 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007567 OS << "[libclang:" << Name << ':';
7568
Alp Toker1a86ad22014-07-06 06:24:00 +00007569#ifdef USE_DARWIN_THREADS
7570 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007571 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7572 OS << tid << ':';
7573#endif
7574
7575 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7576 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
Yaron Keren09fb7c62015-03-10 07:33:23 +00007577 OS << Msg << '\n';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007578
7579 if (Trace) {
Zachary Turner1fe2a8d2015-03-05 19:15:09 +00007580 llvm::sys::PrintStackTrace(OS);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007581 OS << "--------------------------------------------------\n";
7582 }
7583}