blob: 1a34f5a638f4f87349236dbd229614827a793b7a [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
667bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
668 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
669 return Visit(TSInfo->getTypeLoc());
670
671 return false;
672}
673
674bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
675 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
676 return Visit(TSInfo->getTypeLoc());
677
678 return false;
679}
680
681bool CursorVisitor::VisitTagDecl(TagDecl *D) {
682 return VisitDeclContext(D);
683}
684
685bool CursorVisitor::VisitClassTemplateSpecializationDecl(
686 ClassTemplateSpecializationDecl *D) {
687 bool ShouldVisitBody = false;
688 switch (D->getSpecializationKind()) {
689 case TSK_Undeclared:
690 case TSK_ImplicitInstantiation:
691 // Nothing to visit
692 return false;
693
694 case TSK_ExplicitInstantiationDeclaration:
695 case TSK_ExplicitInstantiationDefinition:
696 break;
697
698 case TSK_ExplicitSpecialization:
699 ShouldVisitBody = true;
700 break;
701 }
702
703 // Visit the template arguments used in the specialization.
704 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
705 TypeLoc TL = SpecType->getTypeLoc();
David Blaikie6adc78e2013-02-18 22:06:02 +0000706 if (TemplateSpecializationTypeLoc TSTLoc =
707 TL.getAs<TemplateSpecializationTypeLoc>()) {
708 for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
709 if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000710 return true;
711 }
712 }
713
714 if (ShouldVisitBody && VisitCXXRecordDecl(D))
715 return true;
716
717 return false;
718}
719
720bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
721 ClassTemplatePartialSpecializationDecl *D) {
722 // FIXME: Visit the "outer" template parameter lists on the TagDecl
723 // before visiting these template parameters.
724 if (VisitTemplateParameters(D->getTemplateParameters()))
725 return true;
726
727 // Visit the partial specialization arguments.
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000728 const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
729 const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
730 for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
Guy Benyei11169dd2012-12-18 14:30:41 +0000731 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
732 return true;
733
734 return VisitCXXRecordDecl(D);
735}
736
737bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
738 // Visit the default argument.
739 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
740 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
741 if (Visit(DefArg->getTypeLoc()))
742 return true;
743
744 return false;
745}
746
747bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
748 if (Expr *Init = D->getInitExpr())
749 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
750 return false;
751}
752
753bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000754 unsigned NumParamList = DD->getNumTemplateParameterLists();
755 for (unsigned i = 0; i < NumParamList; i++) {
756 TemplateParameterList* Params = DD->getTemplateParameterList(i);
757 if (VisitTemplateParameters(Params))
758 return true;
759 }
760
Guy Benyei11169dd2012-12-18 14:30:41 +0000761 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
762 if (Visit(TSInfo->getTypeLoc()))
763 return true;
764
765 // Visit the nested-name-specifier, if present.
766 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
767 if (VisitNestedNameSpecifierLoc(QualifierLoc))
768 return true;
769
770 return false;
771}
772
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000773/// \brief Compare two base or member initializers based on their source order.
774static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
775 CXXCtorInitializer *const *Y) {
776 return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
777}
778
Guy Benyei11169dd2012-12-18 14:30:41 +0000779bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000780 unsigned NumParamList = ND->getNumTemplateParameterLists();
781 for (unsigned i = 0; i < NumParamList; i++) {
782 TemplateParameterList* Params = ND->getTemplateParameterList(i);
783 if (VisitTemplateParameters(Params))
784 return true;
785 }
786
Guy Benyei11169dd2012-12-18 14:30:41 +0000787 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
788 // Visit the function declaration's syntactic components in the order
789 // written. This requires a bit of work.
790 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
David Blaikie6adc78e2013-02-18 22:06:02 +0000791 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Guy Benyei11169dd2012-12-18 14:30:41 +0000792
793 // If we have a function declared directly (without the use of a typedef),
794 // visit just the return type. Otherwise, just visit the function's type
795 // now.
Alp Toker42a16a62014-01-25 23:51:36 +0000796 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getReturnLoc())) ||
Guy Benyei11169dd2012-12-18 14:30:41 +0000797 (!FTL && Visit(TL)))
798 return true;
799
800 // Visit the nested-name-specifier, if present.
801 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
802 if (VisitNestedNameSpecifierLoc(QualifierLoc))
803 return true;
804
805 // Visit the declaration name.
Argyrios Kyrtzidis4a4d2b42014-02-09 08:13:47 +0000806 if (!isa<CXXDestructorDecl>(ND))
807 if (VisitDeclarationNameInfo(ND->getNameInfo()))
808 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +0000809
810 // FIXME: Visit explicitly-specified template arguments!
811
812 // Visit the function parameters, if we have a function type.
David Blaikie6adc78e2013-02-18 22:06:02 +0000813 if (FTL && VisitFunctionTypeLoc(FTL, true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000814 return true;
815
Bill Wendling44426052012-12-20 19:22:21 +0000816 // FIXME: Attributes?
Guy Benyei11169dd2012-12-18 14:30:41 +0000817 }
818
819 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
820 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
821 // Find the initializers that were written in the source.
822 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
Aaron Ballman0ad78302014-03-13 17:34:31 +0000823 for (auto *I : Constructor->inits()) {
824 if (!I->isWritten())
Guy Benyei11169dd2012-12-18 14:30:41 +0000825 continue;
826
Aaron Ballman0ad78302014-03-13 17:34:31 +0000827 WrittenInits.push_back(I);
Guy Benyei11169dd2012-12-18 14:30:41 +0000828 }
829
830 // Sort the initializers in source order
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000831 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
832 &CompareCXXCtorInitializers);
833
Guy Benyei11169dd2012-12-18 14:30:41 +0000834 // Visit the initializers in source order
835 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
836 CXXCtorInitializer *Init = WrittenInits[I];
837 if (Init->isAnyMemberInitializer()) {
838 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
839 Init->getMemberLocation(), TU)))
840 return true;
841 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
842 if (Visit(TInfo->getTypeLoc()))
843 return true;
844 }
845
846 // Visit the initializer value.
847 if (Expr *Initializer = Init->getInit())
848 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
849 return true;
850 }
851 }
852
853 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
854 return true;
855 }
856
857 return false;
858}
859
860bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
861 if (VisitDeclaratorDecl(D))
862 return true;
863
864 if (Expr *BitWidth = D->getBitWidth())
865 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
866
867 return false;
868}
869
870bool CursorVisitor::VisitVarDecl(VarDecl *D) {
871 if (VisitDeclaratorDecl(D))
872 return true;
873
874 if (Expr *Init = D->getInit())
875 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
876
877 return false;
878}
879
880bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
881 if (VisitDeclaratorDecl(D))
882 return true;
883
884 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
885 if (Expr *DefArg = D->getDefaultArgument())
886 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
887
888 return false;
889}
890
891bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
892 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
893 // before visiting these template parameters.
894 if (VisitTemplateParameters(D->getTemplateParameters()))
895 return true;
896
897 return VisitFunctionDecl(D->getTemplatedDecl());
898}
899
900bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
901 // FIXME: Visit the "outer" template parameter lists on the TagDecl
902 // before visiting these template parameters.
903 if (VisitTemplateParameters(D->getTemplateParameters()))
904 return true;
905
906 return VisitCXXRecordDecl(D->getTemplatedDecl());
907}
908
909bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
910 if (VisitTemplateParameters(D->getTemplateParameters()))
911 return true;
912
913 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
914 VisitTemplateArgumentLoc(D->getDefaultArgument()))
915 return true;
916
917 return false;
918}
919
Douglas Gregor9bda6cf2015-07-07 03:58:14 +0000920bool CursorVisitor::VisitObjCTypeParamDecl(ObjCTypeParamDecl *D) {
921 // Visit the bound, if it's explicit.
922 if (D->hasExplicitBound()) {
923 if (auto TInfo = D->getTypeSourceInfo()) {
924 if (Visit(TInfo->getTypeLoc()))
925 return true;
926 }
927 }
928
929 return false;
930}
931
Guy Benyei11169dd2012-12-18 14:30:41 +0000932bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Alp Toker314cc812014-01-25 16:55:45 +0000933 if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
Guy Benyei11169dd2012-12-18 14:30:41 +0000934 if (Visit(TSInfo->getTypeLoc()))
935 return true;
936
Aaron Ballman43b68be2014-03-07 17:50:17 +0000937 for (const auto *P : ND->params()) {
938 if (Visit(MakeCXCursor(P, TU, RegionOfInterest)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000939 return true;
940 }
941
942 if (ND->isThisDeclarationADefinition() &&
943 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
944 return true;
945
946 return false;
947}
948
949template <typename DeclIt>
950static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
951 SourceManager &SM, SourceLocation EndLoc,
952 SmallVectorImpl<Decl *> &Decls) {
953 DeclIt next = *DI_current;
954 while (++next != DE_current) {
955 Decl *D_next = *next;
956 if (!D_next)
957 break;
958 SourceLocation L = D_next->getLocStart();
959 if (!L.isValid())
960 break;
961 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
962 *DI_current = next;
963 Decls.push_back(D_next);
964 continue;
965 }
966 break;
967 }
968}
969
Guy Benyei11169dd2012-12-18 14:30:41 +0000970bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
971 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
972 // an @implementation can lexically contain Decls that are not properly
973 // nested in the AST. When we identify such cases, we need to retrofit
974 // this nesting here.
975 if (!DI_current && !FileDI_current)
976 return VisitDeclContext(D);
977
978 // Scan the Decls that immediately come after the container
979 // in the current DeclContext. If any fall within the
980 // container's lexical region, stash them into a vector
981 // for later processing.
982 SmallVector<Decl *, 24> DeclsInContainer;
983 SourceLocation EndLoc = D->getSourceRange().getEnd();
984 SourceManager &SM = AU->getSourceManager();
985 if (EndLoc.isValid()) {
986 if (DI_current) {
987 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
988 DeclsInContainer);
989 } else {
990 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
991 DeclsInContainer);
992 }
993 }
994
995 // The common case.
996 if (DeclsInContainer.empty())
997 return VisitDeclContext(D);
998
999 // Get all the Decls in the DeclContext, and sort them with the
1000 // additional ones we've collected. Then visit them.
Aaron Ballman629afae2014-03-07 19:56:05 +00001001 for (auto *SubDecl : D->decls()) {
1002 if (!SubDecl || SubDecl->getLexicalDeclContext() != D ||
1003 SubDecl->getLocStart().isInvalid())
Guy Benyei11169dd2012-12-18 14:30:41 +00001004 continue;
Aaron Ballman629afae2014-03-07 19:56:05 +00001005 DeclsInContainer.push_back(SubDecl);
Guy Benyei11169dd2012-12-18 14:30:41 +00001006 }
1007
1008 // Now sort the Decls so that they appear in lexical order.
1009 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
Benjamin Kramerbbdd7642014-03-01 14:48:57 +00001010 [&SM](Decl *A, Decl *B) {
1011 SourceLocation L_A = A->getLocStart();
1012 SourceLocation L_B = B->getLocStart();
1013 assert(L_A.isValid() && L_B.isValid());
1014 return SM.isBeforeInTranslationUnit(L_A, L_B);
1015 });
Guy Benyei11169dd2012-12-18 14:30:41 +00001016
1017 // Now visit the decls.
1018 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
1019 E = DeclsInContainer.end(); I != E; ++I) {
1020 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek03325582013-02-21 01:29:01 +00001021 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00001022 if (!V.hasValue())
1023 continue;
1024 if (!V.getValue())
1025 return false;
1026 if (Visit(Cursor, true))
1027 return true;
1028 }
1029 return false;
1030}
1031
1032bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1033 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1034 TU)))
1035 return true;
1036
Douglas Gregore9d95f12015-07-07 03:57:35 +00001037 if (VisitObjCTypeParamList(ND->getTypeParamList()))
1038 return true;
1039
Guy Benyei11169dd2012-12-18 14:30:41 +00001040 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1041 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1042 E = ND->protocol_end(); I != E; ++I, ++PL)
1043 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1044 return true;
1045
1046 return VisitObjCContainerDecl(ND);
1047}
1048
1049bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1050 if (!PID->isThisDeclarationADefinition())
1051 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1052
1053 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1054 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1055 E = PID->protocol_end(); I != E; ++I, ++PL)
1056 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1057 return true;
1058
1059 return VisitObjCContainerDecl(PID);
1060}
1061
1062bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1063 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1064 return true;
1065
1066 // FIXME: This implements a workaround with @property declarations also being
1067 // installed in the DeclContext for the @interface. Eventually this code
1068 // should be removed.
1069 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1070 if (!CDecl || !CDecl->IsClassExtension())
1071 return false;
1072
1073 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1074 if (!ID)
1075 return false;
1076
1077 IdentifierInfo *PropertyId = PD->getIdentifier();
1078 ObjCPropertyDecl *prevDecl =
1079 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1080
1081 if (!prevDecl)
1082 return false;
1083
1084 // Visit synthesized methods since they will be skipped when visiting
1085 // the @interface.
1086 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1087 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1088 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1089 return true;
1090
1091 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1092 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1093 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1094 return true;
1095
1096 return false;
1097}
1098
Douglas Gregore9d95f12015-07-07 03:57:35 +00001099bool CursorVisitor::VisitObjCTypeParamList(ObjCTypeParamList *typeParamList) {
1100 if (!typeParamList)
1101 return false;
1102
1103 for (auto *typeParam : *typeParamList) {
1104 // Visit the type parameter.
1105 if (Visit(MakeCXCursor(typeParam, TU, RegionOfInterest)))
1106 return true;
Douglas Gregore9d95f12015-07-07 03:57:35 +00001107 }
1108
1109 return false;
1110}
1111
Guy Benyei11169dd2012-12-18 14:30:41 +00001112bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1113 if (!D->isThisDeclarationADefinition()) {
1114 // Forward declaration is treated like a reference.
1115 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1116 }
1117
Douglas Gregore9d95f12015-07-07 03:57:35 +00001118 // Objective-C type parameters.
1119 if (VisitObjCTypeParamList(D->getTypeParamListAsWritten()))
1120 return true;
1121
Guy Benyei11169dd2012-12-18 14:30:41 +00001122 // Issue callbacks for super class.
1123 if (D->getSuperClass() &&
1124 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1125 D->getSuperClassLoc(),
1126 TU)))
1127 return true;
1128
Douglas Gregore9d95f12015-07-07 03:57:35 +00001129 if (TypeSourceInfo *SuperClassTInfo = D->getSuperClassTInfo())
1130 if (Visit(SuperClassTInfo->getTypeLoc()))
1131 return true;
1132
Guy Benyei11169dd2012-12-18 14:30:41 +00001133 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1134 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1135 E = D->protocol_end(); I != E; ++I, ++PL)
1136 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1137 return true;
1138
1139 return VisitObjCContainerDecl(D);
1140}
1141
1142bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1143 return VisitObjCContainerDecl(D);
1144}
1145
1146bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1147 // 'ID' could be null when dealing with invalid code.
1148 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1149 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1150 return true;
1151
1152 return VisitObjCImplDecl(D);
1153}
1154
1155bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1156#if 0
1157 // Issue callbacks for super class.
1158 // FIXME: No source location information!
1159 if (D->getSuperClass() &&
1160 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1161 D->getSuperClassLoc(),
1162 TU)))
1163 return true;
1164#endif
1165
1166 return VisitObjCImplDecl(D);
1167}
1168
1169bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1170 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1171 if (PD->isIvarNameSpecified())
1172 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1173
1174 return false;
1175}
1176
1177bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1178 return VisitDeclContext(D);
1179}
1180
1181bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1182 // Visit nested-name-specifier.
1183 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1184 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1185 return true;
1186
1187 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1188 D->getTargetNameLoc(), TU));
1189}
1190
1191bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1192 // Visit nested-name-specifier.
1193 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1194 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1195 return true;
1196 }
1197
1198 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1199 return true;
1200
1201 return VisitDeclarationNameInfo(D->getNameInfo());
1202}
1203
1204bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1205 // Visit nested-name-specifier.
1206 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1207 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1208 return true;
1209
1210 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1211 D->getIdentLocation(), TU));
1212}
1213
1214bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1215 // Visit nested-name-specifier.
1216 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1217 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1218 return true;
1219 }
1220
1221 return VisitDeclarationNameInfo(D->getNameInfo());
1222}
1223
1224bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1225 UnresolvedUsingTypenameDecl *D) {
1226 // Visit nested-name-specifier.
1227 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1228 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1229 return true;
1230
1231 return false;
1232}
1233
1234bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1235 switch (Name.getName().getNameKind()) {
1236 case clang::DeclarationName::Identifier:
1237 case clang::DeclarationName::CXXLiteralOperatorName:
1238 case clang::DeclarationName::CXXOperatorName:
1239 case clang::DeclarationName::CXXUsingDirective:
1240 return false;
1241
1242 case clang::DeclarationName::CXXConstructorName:
1243 case clang::DeclarationName::CXXDestructorName:
1244 case clang::DeclarationName::CXXConversionFunctionName:
1245 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1246 return Visit(TSInfo->getTypeLoc());
1247 return false;
1248
1249 case clang::DeclarationName::ObjCZeroArgSelector:
1250 case clang::DeclarationName::ObjCOneArgSelector:
1251 case clang::DeclarationName::ObjCMultiArgSelector:
1252 // FIXME: Per-identifier location info?
1253 return false;
1254 }
1255
1256 llvm_unreachable("Invalid DeclarationName::Kind!");
1257}
1258
1259bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1260 SourceRange Range) {
1261 // FIXME: This whole routine is a hack to work around the lack of proper
1262 // source information in nested-name-specifiers (PR5791). Since we do have
1263 // a beginning source location, we can visit the first component of the
1264 // nested-name-specifier, if it's a single-token component.
1265 if (!NNS)
1266 return false;
1267
1268 // Get the first component in the nested-name-specifier.
1269 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1270 NNS = Prefix;
1271
1272 switch (NNS->getKind()) {
1273 case NestedNameSpecifier::Namespace:
1274 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1275 TU));
1276
1277 case NestedNameSpecifier::NamespaceAlias:
1278 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1279 Range.getBegin(), TU));
1280
1281 case NestedNameSpecifier::TypeSpec: {
1282 // If the type has a form where we know that the beginning of the source
1283 // range matches up with a reference cursor. Visit the appropriate reference
1284 // cursor.
1285 const Type *T = NNS->getAsType();
1286 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1287 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1288 if (const TagType *Tag = dyn_cast<TagType>(T))
1289 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1290 if (const TemplateSpecializationType *TST
1291 = dyn_cast<TemplateSpecializationType>(T))
1292 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1293 break;
1294 }
1295
1296 case NestedNameSpecifier::TypeSpecWithTemplate:
1297 case NestedNameSpecifier::Global:
1298 case NestedNameSpecifier::Identifier:
Nikola Smiljanic67860242014-09-26 00:28:20 +00001299 case NestedNameSpecifier::Super:
Guy Benyei11169dd2012-12-18 14:30:41 +00001300 break;
1301 }
1302
1303 return false;
1304}
1305
1306bool
1307CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1308 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1309 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1310 Qualifiers.push_back(Qualifier);
1311
1312 while (!Qualifiers.empty()) {
1313 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1314 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1315 switch (NNS->getKind()) {
1316 case NestedNameSpecifier::Namespace:
1317 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1318 Q.getLocalBeginLoc(),
1319 TU)))
1320 return true;
1321
1322 break;
1323
1324 case NestedNameSpecifier::NamespaceAlias:
1325 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1326 Q.getLocalBeginLoc(),
1327 TU)))
1328 return true;
1329
1330 break;
1331
1332 case NestedNameSpecifier::TypeSpec:
1333 case NestedNameSpecifier::TypeSpecWithTemplate:
1334 if (Visit(Q.getTypeLoc()))
1335 return true;
1336
1337 break;
1338
1339 case NestedNameSpecifier::Global:
1340 case NestedNameSpecifier::Identifier:
Nikola Smiljanic67860242014-09-26 00:28:20 +00001341 case NestedNameSpecifier::Super:
Guy Benyei11169dd2012-12-18 14:30:41 +00001342 break;
1343 }
1344 }
1345
1346 return false;
1347}
1348
1349bool CursorVisitor::VisitTemplateParameters(
1350 const TemplateParameterList *Params) {
1351 if (!Params)
1352 return false;
1353
1354 for (TemplateParameterList::const_iterator P = Params->begin(),
1355 PEnd = Params->end();
1356 P != PEnd; ++P) {
1357 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1358 return true;
1359 }
1360
1361 return false;
1362}
1363
1364bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1365 switch (Name.getKind()) {
1366 case TemplateName::Template:
1367 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1368
1369 case TemplateName::OverloadedTemplate:
1370 // Visit the overloaded template set.
1371 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1372 return true;
1373
1374 return false;
1375
1376 case TemplateName::DependentTemplate:
1377 // FIXME: Visit nested-name-specifier.
1378 return false;
1379
1380 case TemplateName::QualifiedTemplate:
1381 // FIXME: Visit nested-name-specifier.
1382 return Visit(MakeCursorTemplateRef(
1383 Name.getAsQualifiedTemplateName()->getDecl(),
1384 Loc, TU));
1385
1386 case TemplateName::SubstTemplateTemplateParm:
1387 return Visit(MakeCursorTemplateRef(
1388 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1389 Loc, TU));
1390
1391 case TemplateName::SubstTemplateTemplateParmPack:
1392 return Visit(MakeCursorTemplateRef(
1393 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1394 Loc, TU));
1395 }
1396
1397 llvm_unreachable("Invalid TemplateName::Kind!");
1398}
1399
1400bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1401 switch (TAL.getArgument().getKind()) {
1402 case TemplateArgument::Null:
1403 case TemplateArgument::Integral:
1404 case TemplateArgument::Pack:
1405 return false;
1406
1407 case TemplateArgument::Type:
1408 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1409 return Visit(TSInfo->getTypeLoc());
1410 return false;
1411
1412 case TemplateArgument::Declaration:
1413 if (Expr *E = TAL.getSourceDeclExpression())
1414 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1415 return false;
1416
1417 case TemplateArgument::NullPtr:
1418 if (Expr *E = TAL.getSourceNullPtrExpression())
1419 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1420 return false;
1421
1422 case TemplateArgument::Expression:
1423 if (Expr *E = TAL.getSourceExpression())
1424 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1425 return false;
1426
1427 case TemplateArgument::Template:
1428 case TemplateArgument::TemplateExpansion:
1429 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1430 return true;
1431
1432 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1433 TAL.getTemplateNameLoc());
1434 }
1435
1436 llvm_unreachable("Invalid TemplateArgument::Kind!");
1437}
1438
1439bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1440 return VisitDeclContext(D);
1441}
1442
1443bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1444 return Visit(TL.getUnqualifiedLoc());
1445}
1446
1447bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1448 ASTContext &Context = AU->getASTContext();
1449
1450 // Some builtin types (such as Objective-C's "id", "sel", and
1451 // "Class") have associated declarations. Create cursors for those.
1452 QualType VisitType;
1453 switch (TL.getTypePtr()->getKind()) {
1454
1455 case BuiltinType::Void:
1456 case BuiltinType::NullPtr:
1457 case BuiltinType::Dependent:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001458 case BuiltinType::OCLImage1d:
1459 case BuiltinType::OCLImage1dArray:
1460 case BuiltinType::OCLImage1dBuffer:
1461 case BuiltinType::OCLImage2d:
1462 case BuiltinType::OCLImage2dArray:
Alexey Bader9c8453f2015-09-15 11:18:52 +00001463 case BuiltinType::OCLImage2dDepth:
1464 case BuiltinType::OCLImage2dArrayDepth:
1465 case BuiltinType::OCLImage2dMSAA:
1466 case BuiltinType::OCLImage2dArrayMSAA:
1467 case BuiltinType::OCLImage2dMSAADepth:
1468 case BuiltinType::OCLImage2dArrayMSAADepth:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001469 case BuiltinType::OCLImage3d:
NAKAMURA Takumi288c42e2013-02-07 12:47:42 +00001470 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +00001471 case BuiltinType::OCLEvent:
Alexey Bader9c8453f2015-09-15 11:18:52 +00001472 case BuiltinType::OCLClkEvent:
1473 case BuiltinType::OCLQueue:
1474 case BuiltinType::OCLNDRange:
1475 case BuiltinType::OCLReserveID:
Guy Benyei11169dd2012-12-18 14:30:41 +00001476#define BUILTIN_TYPE(Id, SingletonId)
1477#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1478#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1479#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1480#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1481#include "clang/AST/BuiltinTypes.def"
1482 break;
1483
1484 case BuiltinType::ObjCId:
1485 VisitType = Context.getObjCIdType();
1486 break;
1487
1488 case BuiltinType::ObjCClass:
1489 VisitType = Context.getObjCClassType();
1490 break;
1491
1492 case BuiltinType::ObjCSel:
1493 VisitType = Context.getObjCSelType();
1494 break;
1495 }
1496
1497 if (!VisitType.isNull()) {
1498 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1499 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1500 TU));
1501 }
1502
1503 return false;
1504}
1505
1506bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1507 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1508}
1509
1510bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1511 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1512}
1513
1514bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1515 if (TL.isDefinition())
1516 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1517
1518 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1519}
1520
1521bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1522 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1523}
1524
1525bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
Hans Wennborg59dbe862015-09-29 20:56:43 +00001526 return Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +00001527}
1528
1529bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1530 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1531 return true;
1532
Douglas Gregore9d95f12015-07-07 03:57:35 +00001533 for (unsigned I = 0, N = TL.getNumTypeArgs(); I != N; ++I) {
1534 if (Visit(TL.getTypeArgTInfo(I)->getTypeLoc()))
1535 return true;
1536 }
1537
Guy Benyei11169dd2012-12-18 14:30:41 +00001538 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1539 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1540 TU)))
1541 return true;
1542 }
1543
1544 return false;
1545}
1546
1547bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1548 return Visit(TL.getPointeeLoc());
1549}
1550
1551bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1552 return Visit(TL.getInnerLoc());
1553}
1554
1555bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1556 return Visit(TL.getPointeeLoc());
1557}
1558
1559bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1560 return Visit(TL.getPointeeLoc());
1561}
1562
1563bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1564 return Visit(TL.getPointeeLoc());
1565}
1566
1567bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1568 return Visit(TL.getPointeeLoc());
1569}
1570
1571bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1572 return Visit(TL.getPointeeLoc());
1573}
1574
1575bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1576 return Visit(TL.getModifiedLoc());
1577}
1578
1579bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1580 bool SkipResultType) {
Alp Toker42a16a62014-01-25 23:51:36 +00001581 if (!SkipResultType && Visit(TL.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001582 return true;
1583
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00001584 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1585 if (Decl *D = TL.getParam(I))
Guy Benyei11169dd2012-12-18 14:30:41 +00001586 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1587 return true;
1588
1589 return false;
1590}
1591
1592bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1593 if (Visit(TL.getElementLoc()))
1594 return true;
1595
1596 if (Expr *Size = TL.getSizeExpr())
1597 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1598
1599 return false;
1600}
1601
Reid Kleckner8a365022013-06-24 17:51:48 +00001602bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1603 return Visit(TL.getOriginalLoc());
1604}
1605
Reid Kleckner0503a872013-12-05 01:23:43 +00001606bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1607 return Visit(TL.getOriginalLoc());
1608}
1609
Guy Benyei11169dd2012-12-18 14:30:41 +00001610bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1611 TemplateSpecializationTypeLoc TL) {
1612 // Visit the template name.
1613 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1614 TL.getTemplateNameLoc()))
1615 return true;
1616
1617 // Visit the template arguments.
1618 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1619 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1620 return true;
1621
1622 return false;
1623}
1624
1625bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1626 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1627}
1628
1629bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1630 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1631 return Visit(TSInfo->getTypeLoc());
1632
1633 return false;
1634}
1635
1636bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1637 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1638 return Visit(TSInfo->getTypeLoc());
1639
1640 return false;
1641}
1642
1643bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
Hans Wennborg59dbe862015-09-29 20:56:43 +00001644 return VisitNestedNameSpecifierLoc(TL.getQualifierLoc());
Guy Benyei11169dd2012-12-18 14:30:41 +00001645}
1646
1647bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1648 DependentTemplateSpecializationTypeLoc TL) {
1649 // Visit the nested-name-specifier, if there is one.
1650 if (TL.getQualifierLoc() &&
1651 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1652 return true;
1653
1654 // Visit the template arguments.
1655 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1656 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1657 return true;
1658
1659 return false;
1660}
1661
1662bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1663 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1664 return true;
1665
1666 return Visit(TL.getNamedTypeLoc());
1667}
1668
1669bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1670 return Visit(TL.getPatternLoc());
1671}
1672
1673bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1674 if (Expr *E = TL.getUnderlyingExpr())
1675 return Visit(MakeCXCursor(E, StmtParent, TU));
1676
1677 return false;
1678}
1679
1680bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1681 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1682}
1683
1684bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1685 return Visit(TL.getValueLoc());
1686}
1687
1688#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1689bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1690 return Visit##PARENT##Loc(TL); \
1691}
1692
1693DEFAULT_TYPELOC_IMPL(Complex, Type)
1694DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1695DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1696DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1697DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1698DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1699DEFAULT_TYPELOC_IMPL(Vector, Type)
1700DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1701DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1702DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1703DEFAULT_TYPELOC_IMPL(Record, TagType)
1704DEFAULT_TYPELOC_IMPL(Enum, TagType)
1705DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1706DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1707DEFAULT_TYPELOC_IMPL(Auto, Type)
1708
1709bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1710 // Visit the nested-name-specifier, if present.
1711 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1712 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1713 return true;
1714
1715 if (D->isCompleteDefinition()) {
Aaron Ballman574705e2014-03-13 15:41:46 +00001716 for (const auto &I : D->bases()) {
1717 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001718 return true;
1719 }
1720 }
1721
1722 return VisitTagDecl(D);
1723}
1724
1725bool CursorVisitor::VisitAttributes(Decl *D) {
Aaron Ballmanb97112e2014-03-08 22:19:01 +00001726 for (const auto *I : D->attrs())
1727 if (Visit(MakeCXCursor(I, D, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001728 return true;
1729
1730 return false;
1731}
1732
1733//===----------------------------------------------------------------------===//
1734// Data-recursive visitor methods.
1735//===----------------------------------------------------------------------===//
1736
1737namespace {
1738#define DEF_JOB(NAME, DATA, KIND)\
1739class NAME : public VisitorJob {\
1740public:\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001741 NAME(const DATA *d, CXCursor parent) : \
1742 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei11169dd2012-12-18 14:30:41 +00001743 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001744 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei11169dd2012-12-18 14:30:41 +00001745};
1746
1747DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1748DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1749DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1750DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1751DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1752 ExplicitTemplateArgsVisitKind)
1753DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1754DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1755DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1756#undef DEF_JOB
1757
1758class DeclVisit : public VisitorJob {
1759public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001760 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei11169dd2012-12-18 14:30:41 +00001761 VisitorJob(parent, VisitorJob::DeclVisitKind,
Craig Topper69186e72014-06-08 08:38:04 +00001762 D, isFirst ? (void*) 1 : (void*) nullptr) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001763 static bool classof(const VisitorJob *VJ) {
1764 return VJ->getKind() == DeclVisitKind;
1765 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001766 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Dmitri Gribenkoe5423a72015-03-23 19:23:50 +00001767 bool isFirst() const { return data[1] != nullptr; }
Guy Benyei11169dd2012-12-18 14:30:41 +00001768};
1769class TypeLocVisit : public VisitorJob {
1770public:
1771 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1772 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1773 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1774
1775 static bool classof(const VisitorJob *VJ) {
1776 return VJ->getKind() == TypeLocVisitKind;
1777 }
1778
1779 TypeLoc get() const {
1780 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001781 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001782 }
1783};
1784
1785class LabelRefVisit : public VisitorJob {
1786public:
1787 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1788 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1789 labelLoc.getPtrEncoding()) {}
1790
1791 static bool classof(const VisitorJob *VJ) {
1792 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1793 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001794 const LabelDecl *get() const {
1795 return static_cast<const LabelDecl *>(data[0]);
1796 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001797 SourceLocation getLoc() const {
1798 return SourceLocation::getFromPtrEncoding(data[1]); }
1799};
1800
1801class NestedNameSpecifierLocVisit : public VisitorJob {
1802public:
1803 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1804 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1805 Qualifier.getNestedNameSpecifier(),
1806 Qualifier.getOpaqueData()) { }
1807
1808 static bool classof(const VisitorJob *VJ) {
1809 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1810 }
1811
1812 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001813 return NestedNameSpecifierLoc(
1814 const_cast<NestedNameSpecifier *>(
1815 static_cast<const NestedNameSpecifier *>(data[0])),
1816 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001817 }
1818};
1819
1820class DeclarationNameInfoVisit : public VisitorJob {
1821public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001822 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001823 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001824 static bool classof(const VisitorJob *VJ) {
1825 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1826 }
1827 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001828 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001829 switch (S->getStmtClass()) {
1830 default:
1831 llvm_unreachable("Unhandled Stmt");
1832 case clang::Stmt::MSDependentExistsStmtClass:
1833 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1834 case Stmt::CXXDependentScopeMemberExprClass:
1835 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1836 case Stmt::DependentScopeDeclRefExprClass:
1837 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001838 case Stmt::OMPCriticalDirectiveClass:
1839 return cast<OMPCriticalDirective>(S)->getDirectiveName();
Guy Benyei11169dd2012-12-18 14:30:41 +00001840 }
1841 }
1842};
1843class MemberRefVisit : public VisitorJob {
1844public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001845 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei11169dd2012-12-18 14:30:41 +00001846 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1847 L.getPtrEncoding()) {}
1848 static bool classof(const VisitorJob *VJ) {
1849 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1850 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001851 const FieldDecl *get() const {
1852 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001853 }
1854 SourceLocation getLoc() const {
1855 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1856 }
1857};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001858class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001859 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001860 VisitorWorkList &WL;
1861 CXCursor Parent;
1862public:
1863 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1864 : WL(wl), Parent(parent) {}
1865
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001866 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1867 void VisitBlockExpr(const BlockExpr *B);
1868 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1869 void VisitCompoundStmt(const CompoundStmt *S);
1870 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1871 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1872 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1873 void VisitCXXNewExpr(const CXXNewExpr *E);
1874 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1875 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1876 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1877 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1878 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1879 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1880 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1881 void VisitCXXCatchStmt(const CXXCatchStmt *S);
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00001882 void VisitCXXForRangeStmt(const CXXForRangeStmt *S);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001883 void VisitDeclRefExpr(const DeclRefExpr *D);
1884 void VisitDeclStmt(const DeclStmt *S);
1885 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1886 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1887 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1888 void VisitForStmt(const ForStmt *FS);
1889 void VisitGotoStmt(const GotoStmt *GS);
1890 void VisitIfStmt(const IfStmt *If);
1891 void VisitInitListExpr(const InitListExpr *IE);
1892 void VisitMemberExpr(const MemberExpr *M);
1893 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1894 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1895 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1896 void VisitOverloadExpr(const OverloadExpr *E);
1897 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1898 void VisitStmt(const Stmt *S);
1899 void VisitSwitchStmt(const SwitchStmt *S);
1900 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001901 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1902 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1903 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1904 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1905 void VisitVAArgExpr(const VAArgExpr *E);
1906 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1907 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1908 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1909 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001910 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
Alexander Musman3aaab662014-08-19 11:27:13 +00001911 void VisitOMPLoopDirective(const OMPLoopDirective *D);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001912 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00001913 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00001914 void VisitOMPForDirective(const OMPForDirective *D);
Alexander Musmanf82886e2014-09-18 05:12:34 +00001915 void VisitOMPForSimdDirective(const OMPForSimdDirective *D);
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00001916 void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
Alexey Bataev1e0498a2014-06-26 08:21:58 +00001917 void VisitOMPSectionDirective(const OMPSectionDirective *D);
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00001918 void VisitOMPSingleDirective(const OMPSingleDirective *D);
Alexander Musman80c22892014-07-17 08:54:58 +00001919 void VisitOMPMasterDirective(const OMPMasterDirective *D);
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001920 void VisitOMPCriticalDirective(const OMPCriticalDirective *D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00001921 void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
Alexander Musmane4e893b2014-09-23 09:33:00 +00001922 void VisitOMPParallelForSimdDirective(const OMPParallelForSimdDirective *D);
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00001923 void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective *D);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00001924 void VisitOMPTaskDirective(const OMPTaskDirective *D);
Alexey Bataev68446b72014-07-18 07:47:19 +00001925 void VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D);
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00001926 void VisitOMPBarrierDirective(const OMPBarrierDirective *D);
Alexey Bataev2df347a2014-07-18 10:17:07 +00001927 void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00001928 void VisitOMPTaskgroupDirective(const OMPTaskgroupDirective *D);
Alexey Bataev6d4ed052015-07-01 06:57:41 +00001929 void
1930 VisitOMPCancellationPointDirective(const OMPCancellationPointDirective *D);
Alexey Bataev80909872015-07-02 11:25:17 +00001931 void VisitOMPCancelDirective(const OMPCancelDirective *D);
Alexey Bataev6125da92014-07-21 11:26:11 +00001932 void VisitOMPFlushDirective(const OMPFlushDirective *D);
Alexey Bataev9fb6e642014-07-22 06:45:04 +00001933 void VisitOMPOrderedDirective(const OMPOrderedDirective *D);
Alexey Bataev0162e452014-07-22 10:10:35 +00001934 void VisitOMPAtomicDirective(const OMPAtomicDirective *D);
Alexey Bataev0bd520b2014-09-19 08:19:49 +00001935 void VisitOMPTargetDirective(const OMPTargetDirective *D);
Michael Wong65f367f2015-07-21 13:44:28 +00001936 void VisitOMPTargetDataDirective(const OMPTargetDataDirective *D);
Alexey Bataev13314bf2014-10-09 04:18:56 +00001937 void VisitOMPTeamsDirective(const OMPTeamsDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001938
Guy Benyei11169dd2012-12-18 14:30:41 +00001939private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001940 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001941 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1942 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001943 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1944 void AddStmt(const Stmt *S);
1945 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001946 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001947 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001948 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001949};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00001950} // end anonyous namespace
Guy Benyei11169dd2012-12-18 14:30:41 +00001951
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001952void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001953 // 'S' should always be non-null, since it comes from the
1954 // statement we are visiting.
1955 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1956}
1957
1958void
1959EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1960 if (Qualifier)
1961 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1962}
1963
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001964void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001965 if (S)
1966 WL.push_back(StmtVisit(S, Parent));
1967}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001968void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001969 if (D)
1970 WL.push_back(DeclVisit(D, Parent, isFirst));
1971}
1972void EnqueueVisitor::
1973 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1974 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001975 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001976}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001977void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001978 if (D)
1979 WL.push_back(MemberRefVisit(D, L, Parent));
1980}
1981void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1982 if (TI)
1983 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1984 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001985void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001986 unsigned size = WL.size();
Benjamin Kramer642f1732015-07-02 21:03:14 +00001987 for (const Stmt *SubStmt : S->children()) {
1988 AddStmt(SubStmt);
Guy Benyei11169dd2012-12-18 14:30:41 +00001989 }
1990 if (size == WL.size())
1991 return;
1992 // Now reverse the entries we just added. This will match the DFS
1993 // ordering performed by the worklist.
1994 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1995 std::reverse(I, E);
1996}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001997namespace {
1998class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1999 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00002000 /// \brief Process clauses with list of variables.
2001 template <typename T>
2002 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002003public:
2004 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
2005#define OPENMP_CLAUSE(Name, Class) \
2006 void Visit##Class(const Class *C);
2007#include "clang/Basic/OpenMPKinds.def"
2008};
2009
Alexey Bataevaadd52e2014-02-13 05:29:23 +00002010void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
2011 Visitor->AddStmt(C->getCondition());
2012}
2013
Alexey Bataev3778b602014-07-17 07:32:53 +00002014void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
2015 Visitor->AddStmt(C->getCondition());
2016}
2017
Alexey Bataev568a8332014-03-06 06:15:19 +00002018void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
2019 Visitor->AddStmt(C->getNumThreads());
2020}
2021
Alexey Bataev62c87d22014-03-21 04:51:18 +00002022void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
2023 Visitor->AddStmt(C->getSafelen());
2024}
2025
Alexey Bataev66b15b52015-08-21 11:14:16 +00002026void OMPClauseEnqueue::VisitOMPSimdlenClause(const OMPSimdlenClause *C) {
2027 Visitor->AddStmt(C->getSimdlen());
2028}
2029
Alexander Musman8bd31e62014-05-27 15:12:19 +00002030void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
2031 Visitor->AddStmt(C->getNumForLoops());
2032}
2033
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002034void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00002035
Alexey Bataevbcbadb62014-05-06 06:04:14 +00002036void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
2037
Alexey Bataev56dafe82014-06-20 07:16:17 +00002038void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
2039 Visitor->AddStmt(C->getChunkSize());
Alexey Bataev040d5402015-05-12 08:35:28 +00002040 Visitor->AddStmt(C->getHelperChunkSize());
Alexey Bataev56dafe82014-06-20 07:16:17 +00002041}
2042
Alexey Bataev10e775f2015-07-30 11:36:16 +00002043void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *C) {
2044 Visitor->AddStmt(C->getNumForLoops());
2045}
Alexey Bataev142e1fc2014-06-20 09:44:06 +00002046
Alexey Bataev236070f2014-06-20 11:19:47 +00002047void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
2048
Alexey Bataev7aea99a2014-07-17 12:19:31 +00002049void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
2050
Alexey Bataev74ba3a52014-07-17 12:47:03 +00002051void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
2052
Alexey Bataevf98b00c2014-07-23 02:27:21 +00002053void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}
2054
Alexey Bataevdea47612014-07-23 07:46:59 +00002055void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {}
2056
Alexey Bataev67a4f222014-07-23 10:25:33 +00002057void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {}
2058
Alexey Bataev459dec02014-07-24 06:46:57 +00002059void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}
2060
Alexey Bataev82bad8b2014-07-24 08:55:34 +00002061void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
2062
Alexey Bataev346265e2015-09-25 10:37:12 +00002063void OMPClauseEnqueue::VisitOMPThreadsClause(const OMPThreadsClause *) {}
2064
Alexey Bataevd14d1e62015-09-28 06:39:35 +00002065void OMPClauseEnqueue::VisitOMPSIMDClause(const OMPSIMDClause *) {}
2066
Michael Wonge710d542015-08-07 16:16:36 +00002067void OMPClauseEnqueue::VisitOMPDeviceClause(const OMPDeviceClause *C) {
2068 Visitor->AddStmt(C->getDevice());
2069}
2070
Alexey Bataev756c1962013-09-24 03:17:45 +00002071template<typename T>
2072void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Alexey Bataev03b340a2014-10-21 03:16:40 +00002073 for (const auto *I : Node->varlists()) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00002074 Visitor->AddStmt(I);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002075 }
Alexey Bataev756c1962013-09-24 03:17:45 +00002076}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002077
2078void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002079 VisitOMPClauseList(C);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002080 for (const auto *E : C->private_copies()) {
2081 Visitor->AddStmt(E);
2082 }
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002083}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002084void OMPClauseEnqueue::VisitOMPFirstprivateClause(
2085 const OMPFirstprivateClause *C) {
2086 VisitOMPClauseList(C);
2087}
Alexander Musman1bb328c2014-06-04 13:06:39 +00002088void OMPClauseEnqueue::VisitOMPLastprivateClause(
2089 const OMPLastprivateClause *C) {
2090 VisitOMPClauseList(C);
Alexey Bataev38e89532015-04-16 04:54:05 +00002091 for (auto *E : C->private_copies()) {
2092 Visitor->AddStmt(E);
2093 }
2094 for (auto *E : C->source_exprs()) {
2095 Visitor->AddStmt(E);
2096 }
2097 for (auto *E : C->destination_exprs()) {
2098 Visitor->AddStmt(E);
2099 }
2100 for (auto *E : C->assignment_ops()) {
2101 Visitor->AddStmt(E);
2102 }
Alexander Musman1bb328c2014-06-04 13:06:39 +00002103}
Alexey Bataev758e55e2013-09-06 18:03:48 +00002104void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002105 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00002106}
Alexey Bataevc5e02582014-06-16 07:08:35 +00002107void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
2108 VisitOMPClauseList(C);
Alexey Bataevf24e7b12015-10-08 09:10:53 +00002109 for (auto *E : C->privates()) {
2110 Visitor->AddStmt(E);
2111 }
Alexey Bataev794ba0d2015-04-10 10:43:45 +00002112 for (auto *E : C->lhs_exprs()) {
2113 Visitor->AddStmt(E);
2114 }
2115 for (auto *E : C->rhs_exprs()) {
2116 Visitor->AddStmt(E);
2117 }
2118 for (auto *E : C->reduction_ops()) {
2119 Visitor->AddStmt(E);
2120 }
Alexey Bataevc5e02582014-06-16 07:08:35 +00002121}
Alexander Musman8dba6642014-04-22 13:09:42 +00002122void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2123 VisitOMPClauseList(C);
Alexey Bataevbd9fec12015-08-18 06:47:21 +00002124 for (const auto *E : C->privates()) {
2125 Visitor->AddStmt(E);
2126 }
Alexander Musman3276a272015-03-21 10:12:56 +00002127 for (const auto *E : C->inits()) {
2128 Visitor->AddStmt(E);
2129 }
2130 for (const auto *E : C->updates()) {
2131 Visitor->AddStmt(E);
2132 }
2133 for (const auto *E : C->finals()) {
2134 Visitor->AddStmt(E);
2135 }
Alexander Musman8dba6642014-04-22 13:09:42 +00002136 Visitor->AddStmt(C->getStep());
Alexander Musman3276a272015-03-21 10:12:56 +00002137 Visitor->AddStmt(C->getCalcStep());
Alexander Musman8dba6642014-04-22 13:09:42 +00002138}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002139void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2140 VisitOMPClauseList(C);
2141 Visitor->AddStmt(C->getAlignment());
2142}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002143void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2144 VisitOMPClauseList(C);
Alexey Bataevf56f98c2015-04-16 05:39:01 +00002145 for (auto *E : C->source_exprs()) {
2146 Visitor->AddStmt(E);
2147 }
2148 for (auto *E : C->destination_exprs()) {
2149 Visitor->AddStmt(E);
2150 }
2151 for (auto *E : C->assignment_ops()) {
2152 Visitor->AddStmt(E);
2153 }
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002154}
Alexey Bataevbae9a792014-06-27 10:37:06 +00002155void
2156OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
2157 VisitOMPClauseList(C);
Alexey Bataeva63048e2015-03-23 06:18:07 +00002158 for (auto *E : C->source_exprs()) {
2159 Visitor->AddStmt(E);
2160 }
2161 for (auto *E : C->destination_exprs()) {
2162 Visitor->AddStmt(E);
2163 }
2164 for (auto *E : C->assignment_ops()) {
2165 Visitor->AddStmt(E);
2166 }
Alexey Bataevbae9a792014-06-27 10:37:06 +00002167}
Alexey Bataev6125da92014-07-21 11:26:11 +00002168void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2169 VisitOMPClauseList(C);
2170}
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +00002171void OMPClauseEnqueue::VisitOMPDependClause(const OMPDependClause *C) {
2172 VisitOMPClauseList(C);
2173}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002174}
Alexey Bataev756c1962013-09-24 03:17:45 +00002175
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002176void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2177 unsigned size = WL.size();
2178 OMPClauseEnqueue Visitor(this);
2179 Visitor.Visit(S);
2180 if (size == WL.size())
2181 return;
2182 // Now reverse the entries we just added. This will match the DFS
2183 // ordering performed by the worklist.
2184 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2185 std::reverse(I, E);
2186}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002187void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002188 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2189}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002190void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002191 AddDecl(B->getBlockDecl());
2192}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002193void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002194 EnqueueChildren(E);
2195 AddTypeLoc(E->getTypeSourceInfo());
2196}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002197void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
Pete Cooper57d3f142015-07-30 17:22:52 +00002198 for (auto &I : llvm::reverse(S->body()))
2199 AddStmt(I);
Guy Benyei11169dd2012-12-18 14:30:41 +00002200}
2201void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002202VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002203 AddStmt(S->getSubStmt());
2204 AddDeclarationNameInfo(S);
2205 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2206 AddNestedNameSpecifierLoc(QualifierLoc);
2207}
2208
2209void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002210VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002211 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2212 AddDeclarationNameInfo(E);
2213 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2214 AddNestedNameSpecifierLoc(QualifierLoc);
2215 if (!E->isImplicitAccess())
2216 AddStmt(E->getBase());
2217}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002218void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002219 // Enqueue the initializer , if any.
2220 AddStmt(E->getInitializer());
2221 // Enqueue the array size, if any.
2222 AddStmt(E->getArraySize());
2223 // Enqueue the allocated type.
2224 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2225 // Enqueue the placement arguments.
2226 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2227 AddStmt(E->getPlacementArg(I-1));
2228}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002229void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002230 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2231 AddStmt(CE->getArg(I-1));
2232 AddStmt(CE->getCallee());
2233 AddStmt(CE->getArg(0));
2234}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002235void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2236 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002237 // Visit the name of the type being destroyed.
2238 AddTypeLoc(E->getDestroyedTypeInfo());
2239 // Visit the scope type that looks disturbingly like the nested-name-specifier
2240 // but isn't.
2241 AddTypeLoc(E->getScopeTypeInfo());
2242 // Visit the nested-name-specifier.
2243 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2244 AddNestedNameSpecifierLoc(QualifierLoc);
2245 // Visit base expression.
2246 AddStmt(E->getBase());
2247}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002248void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2249 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002250 AddTypeLoc(E->getTypeSourceInfo());
2251}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002252void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2253 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002254 EnqueueChildren(E);
2255 AddTypeLoc(E->getTypeSourceInfo());
2256}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002257void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002258 EnqueueChildren(E);
2259 if (E->isTypeOperand())
2260 AddTypeLoc(E->getTypeOperandSourceInfo());
2261}
2262
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002263void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2264 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002265 EnqueueChildren(E);
2266 AddTypeLoc(E->getTypeSourceInfo());
2267}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002268void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002269 EnqueueChildren(E);
2270 if (E->isTypeOperand())
2271 AddTypeLoc(E->getTypeOperandSourceInfo());
2272}
2273
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002274void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002275 EnqueueChildren(S);
2276 AddDecl(S->getExceptionDecl());
2277}
2278
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002279void EnqueueVisitor::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002280 AddStmt(S->getBody());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002281 AddStmt(S->getRangeInit());
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002282 AddDecl(S->getLoopVariable());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002283}
2284
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002285void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002286 if (DR->hasExplicitTemplateArgs()) {
2287 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2288 }
2289 WL.push_back(DeclRefExprParts(DR, Parent));
2290}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002291void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2292 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002293 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2294 AddDeclarationNameInfo(E);
2295 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2296}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002297void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002298 unsigned size = WL.size();
2299 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002300 for (const auto *D : S->decls()) {
2301 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002302 isFirst = false;
2303 }
2304 if (size == WL.size())
2305 return;
2306 // Now reverse the entries we just added. This will match the DFS
2307 // ordering performed by the worklist.
2308 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2309 std::reverse(I, E);
2310}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002311void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002312 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002313 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002314 D = E->designators_rbegin(), DEnd = E->designators_rend();
2315 D != DEnd; ++D) {
2316 if (D->isFieldDesignator()) {
2317 if (FieldDecl *Field = D->getField())
2318 AddMemberRef(Field, D->getFieldLoc());
2319 continue;
2320 }
2321 if (D->isArrayDesignator()) {
2322 AddStmt(E->getArrayIndex(*D));
2323 continue;
2324 }
2325 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2326 AddStmt(E->getArrayRangeEnd(*D));
2327 AddStmt(E->getArrayRangeStart(*D));
2328 }
2329}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002330void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002331 EnqueueChildren(E);
2332 AddTypeLoc(E->getTypeInfoAsWritten());
2333}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002334void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002335 AddStmt(FS->getBody());
2336 AddStmt(FS->getInc());
2337 AddStmt(FS->getCond());
2338 AddDecl(FS->getConditionVariable());
2339 AddStmt(FS->getInit());
2340}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002341void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002342 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2343}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002344void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002345 AddStmt(If->getElse());
2346 AddStmt(If->getThen());
2347 AddStmt(If->getCond());
2348 AddDecl(If->getConditionVariable());
2349}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002350void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002351 // We care about the syntactic form of the initializer list, only.
2352 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2353 IE = Syntactic;
2354 EnqueueChildren(IE);
2355}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002356void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002357 WL.push_back(MemberExprParts(M, Parent));
2358
2359 // If the base of the member access expression is an implicit 'this', don't
2360 // visit it.
2361 // FIXME: If we ever want to show these implicit accesses, this will be
2362 // unfortunate. However, clang_getCursor() relies on this behavior.
Argyrios Kyrtzidis58d0e7a2015-03-13 04:40:07 +00002363 if (M->isImplicitAccess())
2364 return;
2365
2366 // Ignore base anonymous struct/union fields, otherwise they will shadow the
2367 // real field that that we are interested in.
2368 if (auto *SubME = dyn_cast<MemberExpr>(M->getBase())) {
2369 if (auto *FD = dyn_cast_or_null<FieldDecl>(SubME->getMemberDecl())) {
2370 if (FD->isAnonymousStructOrUnion()) {
2371 AddStmt(SubME->getBase());
2372 return;
2373 }
2374 }
2375 }
2376
2377 AddStmt(M->getBase());
Guy Benyei11169dd2012-12-18 14:30:41 +00002378}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002379void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002380 AddTypeLoc(E->getEncodedTypeSourceInfo());
2381}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002382void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002383 EnqueueChildren(M);
2384 AddTypeLoc(M->getClassReceiverTypeInfo());
2385}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002386void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002387 // Visit the components of the offsetof expression.
2388 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2389 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2390 const OffsetOfNode &Node = E->getComponent(I-1);
2391 switch (Node.getKind()) {
2392 case OffsetOfNode::Array:
2393 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2394 break;
2395 case OffsetOfNode::Field:
2396 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2397 break;
2398 case OffsetOfNode::Identifier:
2399 case OffsetOfNode::Base:
2400 continue;
2401 }
2402 }
2403 // Visit the type into which we're computing the offset.
2404 AddTypeLoc(E->getTypeSourceInfo());
2405}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002406void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002407 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2408 WL.push_back(OverloadExprParts(E, Parent));
2409}
2410void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002411 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002412 EnqueueChildren(E);
2413 if (E->isArgumentType())
2414 AddTypeLoc(E->getArgumentTypeInfo());
2415}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002416void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002417 EnqueueChildren(S);
2418}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002419void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002420 AddStmt(S->getBody());
2421 AddStmt(S->getCond());
2422 AddDecl(S->getConditionVariable());
2423}
2424
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002425void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002426 AddStmt(W->getBody());
2427 AddStmt(W->getCond());
2428 AddDecl(W->getConditionVariable());
2429}
2430
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002431void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002432 for (unsigned I = E->getNumArgs(); I > 0; --I)
2433 AddTypeLoc(E->getArg(I-1));
2434}
2435
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002436void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002437 AddTypeLoc(E->getQueriedTypeSourceInfo());
2438}
2439
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002440void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002441 EnqueueChildren(E);
2442}
2443
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002444void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002445 VisitOverloadExpr(U);
2446 if (!U->isImplicitAccess())
2447 AddStmt(U->getBase());
2448}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002449void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002450 AddStmt(E->getSubExpr());
2451 AddTypeLoc(E->getWrittenTypeInfo());
2452}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002453void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002454 WL.push_back(SizeOfPackExprParts(E, Parent));
2455}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002456void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002457 // If the opaque value has a source expression, just transparently
2458 // visit that. This is useful for (e.g.) pseudo-object expressions.
2459 if (Expr *SourceExpr = E->getSourceExpr())
2460 return Visit(SourceExpr);
2461}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002462void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002463 AddStmt(E->getBody());
2464 WL.push_back(LambdaExprParts(E, Parent));
2465}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002466void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002467 // Treat the expression like its syntactic form.
2468 Visit(E->getSyntacticForm());
2469}
2470
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002471void EnqueueVisitor::VisitOMPExecutableDirective(
2472 const OMPExecutableDirective *D) {
2473 EnqueueChildren(D);
2474 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2475 E = D->clauses().end();
2476 I != E; ++I)
2477 EnqueueChildren(*I);
2478}
2479
Alexander Musman3aaab662014-08-19 11:27:13 +00002480void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
2481 VisitOMPExecutableDirective(D);
2482}
2483
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002484void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2485 VisitOMPExecutableDirective(D);
2486}
2487
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002488void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002489 VisitOMPLoopDirective(D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002490}
2491
Alexey Bataevf29276e2014-06-18 04:14:57 +00002492void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002493 VisitOMPLoopDirective(D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002494}
2495
Alexander Musmanf82886e2014-09-18 05:12:34 +00002496void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
2497 VisitOMPLoopDirective(D);
2498}
2499
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002500void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2501 VisitOMPExecutableDirective(D);
2502}
2503
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002504void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2505 VisitOMPExecutableDirective(D);
2506}
2507
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002508void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2509 VisitOMPExecutableDirective(D);
2510}
2511
Alexander Musman80c22892014-07-17 08:54:58 +00002512void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2513 VisitOMPExecutableDirective(D);
2514}
2515
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002516void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2517 VisitOMPExecutableDirective(D);
2518 AddDeclarationNameInfo(D);
2519}
2520
Alexey Bataev4acb8592014-07-07 13:01:15 +00002521void
2522EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002523 VisitOMPLoopDirective(D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002524}
2525
Alexander Musmane4e893b2014-09-23 09:33:00 +00002526void EnqueueVisitor::VisitOMPParallelForSimdDirective(
2527 const OMPParallelForSimdDirective *D) {
2528 VisitOMPLoopDirective(D);
2529}
2530
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002531void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2532 const OMPParallelSectionsDirective *D) {
2533 VisitOMPExecutableDirective(D);
2534}
2535
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002536void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2537 VisitOMPExecutableDirective(D);
2538}
2539
Alexey Bataev68446b72014-07-18 07:47:19 +00002540void
2541EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2542 VisitOMPExecutableDirective(D);
2543}
2544
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002545void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2546 VisitOMPExecutableDirective(D);
2547}
2548
Alexey Bataev2df347a2014-07-18 10:17:07 +00002549void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2550 VisitOMPExecutableDirective(D);
2551}
2552
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002553void EnqueueVisitor::VisitOMPTaskgroupDirective(
2554 const OMPTaskgroupDirective *D) {
2555 VisitOMPExecutableDirective(D);
2556}
2557
Alexey Bataev6125da92014-07-21 11:26:11 +00002558void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2559 VisitOMPExecutableDirective(D);
2560}
2561
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002562void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2563 VisitOMPExecutableDirective(D);
2564}
2565
Alexey Bataev0162e452014-07-22 10:10:35 +00002566void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2567 VisitOMPExecutableDirective(D);
2568}
2569
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002570void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
2571 VisitOMPExecutableDirective(D);
2572}
2573
Michael Wong65f367f2015-07-21 13:44:28 +00002574void EnqueueVisitor::VisitOMPTargetDataDirective(const
2575 OMPTargetDataDirective *D) {
2576 VisitOMPExecutableDirective(D);
2577}
2578
Alexey Bataev13314bf2014-10-09 04:18:56 +00002579void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {
2580 VisitOMPExecutableDirective(D);
2581}
2582
Alexey Bataev6d4ed052015-07-01 06:57:41 +00002583void EnqueueVisitor::VisitOMPCancellationPointDirective(
2584 const OMPCancellationPointDirective *D) {
2585 VisitOMPExecutableDirective(D);
2586}
2587
Alexey Bataev80909872015-07-02 11:25:17 +00002588void EnqueueVisitor::VisitOMPCancelDirective(const OMPCancelDirective *D) {
2589 VisitOMPExecutableDirective(D);
2590}
2591
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002592void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002593 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2594}
2595
2596bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2597 if (RegionOfInterest.isValid()) {
2598 SourceRange Range = getRawCursorExtent(C);
2599 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2600 return false;
2601 }
2602 return true;
2603}
2604
2605bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2606 while (!WL.empty()) {
2607 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002608 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002609
2610 // Set the Parent field, then back to its old value once we're done.
2611 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2612
2613 switch (LI.getKind()) {
2614 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002615 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002616 if (!D)
2617 continue;
2618
2619 // For now, perform default visitation for Decls.
2620 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2621 cast<DeclVisit>(&LI)->isFirst())))
2622 return true;
2623
2624 continue;
2625 }
2626 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2627 const ASTTemplateArgumentListInfo *ArgList =
2628 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2629 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2630 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2631 Arg != ArgEnd; ++Arg) {
2632 if (VisitTemplateArgumentLoc(*Arg))
2633 return true;
2634 }
2635 continue;
2636 }
2637 case VisitorJob::TypeLocVisitKind: {
2638 // Perform default visitation for TypeLocs.
2639 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2640 return true;
2641 continue;
2642 }
2643 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002644 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002645 if (LabelStmt *stmt = LS->getStmt()) {
2646 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2647 TU))) {
2648 return true;
2649 }
2650 }
2651 continue;
2652 }
2653
2654 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2655 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2656 if (VisitNestedNameSpecifierLoc(V->get()))
2657 return true;
2658 continue;
2659 }
2660
2661 case VisitorJob::DeclarationNameInfoVisitKind: {
2662 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2663 ->get()))
2664 return true;
2665 continue;
2666 }
2667 case VisitorJob::MemberRefVisitKind: {
2668 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2669 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2670 return true;
2671 continue;
2672 }
2673 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002674 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002675 if (!S)
2676 continue;
2677
2678 // Update the current cursor.
2679 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2680 if (!IsInRegionOfInterest(Cursor))
2681 continue;
2682 switch (Visitor(Cursor, Parent, ClientData)) {
2683 case CXChildVisit_Break: return true;
2684 case CXChildVisit_Continue: break;
2685 case CXChildVisit_Recurse:
2686 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002687 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002688 EnqueueWorkList(WL, S);
2689 break;
2690 }
2691 continue;
2692 }
2693 case VisitorJob::MemberExprPartsKind: {
2694 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002695 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002696
2697 // Visit the nested-name-specifier
2698 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2699 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2700 return true;
2701
2702 // Visit the declaration name.
2703 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2704 return true;
2705
2706 // Visit the explicitly-specified template arguments, if any.
2707 if (M->hasExplicitTemplateArgs()) {
2708 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2709 *ArgEnd = Arg + M->getNumTemplateArgs();
2710 Arg != ArgEnd; ++Arg) {
2711 if (VisitTemplateArgumentLoc(*Arg))
2712 return true;
2713 }
2714 }
2715 continue;
2716 }
2717 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002718 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002719 // Visit nested-name-specifier, if present.
2720 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2721 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2722 return true;
2723 // Visit declaration name.
2724 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2725 return true;
2726 continue;
2727 }
2728 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002729 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002730 // Visit the nested-name-specifier.
2731 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2732 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2733 return true;
2734 // Visit the declaration name.
2735 if (VisitDeclarationNameInfo(O->getNameInfo()))
2736 return true;
2737 // Visit the overloaded declaration reference.
2738 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2739 return true;
2740 continue;
2741 }
2742 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002743 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002744 NamedDecl *Pack = E->getPack();
2745 if (isa<TemplateTypeParmDecl>(Pack)) {
2746 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2747 E->getPackLoc(), TU)))
2748 return true;
2749
2750 continue;
2751 }
2752
2753 if (isa<TemplateTemplateParmDecl>(Pack)) {
2754 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2755 E->getPackLoc(), TU)))
2756 return true;
2757
2758 continue;
2759 }
2760
2761 // Non-type template parameter packs and function parameter packs are
2762 // treated like DeclRefExpr cursors.
2763 continue;
2764 }
2765
2766 case VisitorJob::LambdaExprPartsKind: {
2767 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002768 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002769 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2770 CEnd = E->explicit_capture_end();
2771 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002772 // FIXME: Lambda init-captures.
2773 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002774 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002775
Guy Benyei11169dd2012-12-18 14:30:41 +00002776 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2777 C->getLocation(),
2778 TU)))
2779 return true;
2780 }
2781
2782 // Visit parameters and return type, if present.
2783 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2784 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2785 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2786 // Visit the whole type.
2787 if (Visit(TL))
2788 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002789 } else if (FunctionProtoTypeLoc Proto =
2790 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002791 if (E->hasExplicitParameters()) {
2792 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002793 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2794 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002795 return true;
2796 } else {
2797 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002798 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002799 return true;
2800 }
2801 }
2802 }
2803 break;
2804 }
2805
2806 case VisitorJob::PostChildrenVisitKind:
2807 if (PostChildrenVisitor(Parent, ClientData))
2808 return true;
2809 break;
2810 }
2811 }
2812 return false;
2813}
2814
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002815bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002816 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002817 if (!WorkListFreeList.empty()) {
2818 WL = WorkListFreeList.back();
2819 WL->clear();
2820 WorkListFreeList.pop_back();
2821 }
2822 else {
2823 WL = new VisitorWorkList();
2824 WorkListCache.push_back(WL);
2825 }
2826 EnqueueWorkList(*WL, S);
2827 bool result = RunVisitorWorkList(*WL);
2828 WorkListFreeList.push_back(WL);
2829 return result;
2830}
2831
2832namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002833typedef SmallVector<SourceRange, 4> RefNamePieces;
Craig Topper69186e72014-06-08 08:38:04 +00002834RefNamePieces
2835buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
Craig Toppere335f252015-10-04 04:53:55 +00002836 const DeclarationNameInfo &NI, SourceRange QLoc,
Craig Topper69186e72014-06-08 08:38:04 +00002837 const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002838 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2839 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2840 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2841
2842 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2843
2844 RefNamePieces Pieces;
2845
2846 if (WantQualifier && QLoc.isValid())
2847 Pieces.push_back(QLoc);
2848
2849 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2850 Pieces.push_back(NI.getLoc());
2851
2852 if (WantTemplateArgs && TemplateArgs)
2853 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2854 TemplateArgs->RAngleLoc));
2855
2856 if (Kind == DeclarationName::CXXOperatorName) {
2857 Pieces.push_back(SourceLocation::getFromRawEncoding(
2858 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2859 Pieces.push_back(SourceLocation::getFromRawEncoding(
2860 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2861 }
2862
2863 if (WantSinglePiece) {
2864 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2865 Pieces.clear();
2866 Pieces.push_back(R);
2867 }
2868
2869 return Pieces;
2870}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002871}
Guy Benyei11169dd2012-12-18 14:30:41 +00002872
2873//===----------------------------------------------------------------------===//
2874// Misc. API hooks.
2875//===----------------------------------------------------------------------===//
2876
Chad Rosier05c71aa2013-03-27 18:28:23 +00002877static void fatal_error_handler(void *user_data, const std::string& reason,
2878 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002879 // Write the result out to stderr avoiding errs() because raw_ostreams can
2880 // call report_fatal_error.
2881 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2882 ::abort();
2883}
2884
Chandler Carruth66660742014-06-27 16:37:27 +00002885namespace {
2886struct RegisterFatalErrorHandler {
2887 RegisterFatalErrorHandler() {
2888 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2889 }
2890};
2891}
2892
2893static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
2894
Guy Benyei11169dd2012-12-18 14:30:41 +00002895extern "C" {
2896CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2897 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002898 // We use crash recovery to make some of our APIs more reliable, implicitly
2899 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002900 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2901 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002902
Chandler Carruth66660742014-06-27 16:37:27 +00002903 // Look through the managed static to trigger construction of the managed
2904 // static which registers our fatal error handler. This ensures it is only
2905 // registered once.
2906 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00002907
Adrian Prantlbc068582015-07-08 01:00:30 +00002908 // Initialize targets for clang module support.
2909 llvm::InitializeAllTargets();
2910 llvm::InitializeAllTargetMCs();
2911 llvm::InitializeAllAsmPrinters();
2912 llvm::InitializeAllAsmParsers();
2913
Adrian Prantlfb2398d2015-07-17 01:19:54 +00002914 CIndexer *CIdxr = new CIndexer();
2915
Guy Benyei11169dd2012-12-18 14:30:41 +00002916 if (excludeDeclarationsFromPCH)
2917 CIdxr->setOnlyLocalDecls();
2918 if (displayDiagnostics)
2919 CIdxr->setDisplayDiagnostics();
2920
2921 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2922 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2923 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2924 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2925 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2926 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2927
2928 return CIdxr;
2929}
2930
2931void clang_disposeIndex(CXIndex CIdx) {
2932 if (CIdx)
2933 delete static_cast<CIndexer *>(CIdx);
2934}
2935
2936void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2937 if (CIdx)
2938 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2939}
2940
2941unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2942 if (CIdx)
2943 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2944 return 0;
2945}
2946
2947void clang_toggleCrashRecovery(unsigned isEnabled) {
2948 if (isEnabled)
2949 llvm::CrashRecoveryContext::Enable();
2950 else
2951 llvm::CrashRecoveryContext::Disable();
2952}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002953
Guy Benyei11169dd2012-12-18 14:30:41 +00002954CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2955 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002956 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002957 enum CXErrorCode Result =
2958 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002959 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002960 assert((TU && Result == CXError_Success) ||
2961 (!TU && Result != CXError_Success));
2962 return TU;
2963}
2964
2965enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2966 const char *ast_filename,
2967 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002968 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002969 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002970
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002971 if (!CIdx || !ast_filename || !out_TU)
2972 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002973
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002974 LOG_FUNC_SECTION {
2975 *Log << ast_filename;
2976 }
2977
Guy Benyei11169dd2012-12-18 14:30:41 +00002978 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2979 FileSystemOptions FileSystemOpts;
2980
Justin Bognerd512c1e2014-10-15 00:33:06 +00002981 IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
2982 CompilerInstance::createDiagnostics(new DiagnosticOptions());
David Blaikie6f7382d2014-08-10 19:08:04 +00002983 std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
Adrian Prantlfb2398d2015-07-17 01:19:54 +00002984 ast_filename, CXXIdx->getPCHContainerOperations()->getRawReader(), Diags,
Adrian Prantl6b21ab22015-08-27 19:46:20 +00002985 FileSystemOpts, /*UseDebugInfo=*/false,
2986 CXXIdx->getOnlyLocalDecls(), None,
David Blaikie6f7382d2014-08-10 19:08:04 +00002987 /*CaptureDiagnostics=*/true,
2988 /*AllowPCHWithCompilerErrors=*/true,
2989 /*UserFilesAreVolatile=*/true);
2990 *out_TU = MakeCXTranslationUnit(CXXIdx, AU.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002991 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002992}
2993
2994unsigned clang_defaultEditingTranslationUnitOptions() {
2995 return CXTranslationUnit_PrecompiledPreamble |
2996 CXTranslationUnit_CacheCompletionResults;
2997}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002998
Guy Benyei11169dd2012-12-18 14:30:41 +00002999CXTranslationUnit
3000clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
3001 const char *source_filename,
3002 int num_command_line_args,
3003 const char * const *command_line_args,
3004 unsigned num_unsaved_files,
3005 struct CXUnsavedFile *unsaved_files) {
3006 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
3007 return clang_parseTranslationUnit(CIdx, source_filename,
3008 command_line_args, num_command_line_args,
3009 unsaved_files, num_unsaved_files,
3010 Options);
3011}
3012
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003013static CXErrorCode
3014clang_parseTranslationUnit_Impl(CXIndex CIdx, const char *source_filename,
3015 const char *const *command_line_args,
3016 int num_command_line_args,
3017 ArrayRef<CXUnsavedFile> unsaved_files,
3018 unsigned options, CXTranslationUnit *out_TU) {
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003019 // Set up the initial return values.
3020 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00003021 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003022
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003023 // Check arguments.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003024 if (!CIdx || !out_TU)
3025 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003026
Guy Benyei11169dd2012-12-18 14:30:41 +00003027 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3028
3029 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3030 setThreadBackgroundPriority();
3031
3032 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
3033 // FIXME: Add a flag for modules.
3034 TranslationUnitKind TUKind
3035 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00003036 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00003037 = options & CXTranslationUnit_CacheCompletionResults;
3038 bool IncludeBriefCommentsInCodeCompletion
3039 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
3040 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
3041 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
3042
3043 // Configure the diagnostics.
3044 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00003045 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00003046
3047 // Recover resources if we crash before exiting this function.
3048 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
3049 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00003050 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00003051
Ahmed Charlesb8984322014-03-07 20:03:18 +00003052 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3053 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003054
3055 // Recover resources if we crash before exiting this function.
3056 llvm::CrashRecoveryContextCleanupRegistrar<
3057 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3058
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003059 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003060 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003061 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003062 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003063 }
3064
Ahmed Charlesb8984322014-03-07 20:03:18 +00003065 std::unique_ptr<std::vector<const char *>> Args(
3066 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003067
3068 // Recover resources if we crash before exiting this method.
3069 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
3070 ArgsCleanup(Args.get());
3071
3072 // Since the Clang C library is primarily used by batch tools dealing with
3073 // (often very broken) source code, where spell-checking can have a
3074 // significant negative impact on performance (particularly when
3075 // precompiled headers are involved), we disable it by default.
3076 // Only do this if we haven't found a spell-checking-related argument.
3077 bool FoundSpellCheckingArgument = false;
3078 for (int I = 0; I != num_command_line_args; ++I) {
3079 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
3080 strcmp(command_line_args[I], "-fspell-checking") == 0) {
3081 FoundSpellCheckingArgument = true;
3082 break;
3083 }
3084 }
3085 if (!FoundSpellCheckingArgument)
3086 Args->push_back("-fno-spell-checking");
3087
3088 Args->insert(Args->end(), command_line_args,
3089 command_line_args + num_command_line_args);
3090
3091 // The 'source_filename' argument is optional. If the caller does not
3092 // specify it then it is assumed that the source file is specified
3093 // in the actual argument list.
3094 // Put the source file after command_line_args otherwise if '-x' flag is
3095 // present it will be unused.
3096 if (source_filename)
3097 Args->push_back(source_filename);
3098
3099 // Do we need the detailed preprocessing record?
3100 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
3101 Args->push_back("-Xclang");
3102 Args->push_back("-detailed-preprocessing-record");
3103 }
3104
3105 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00003106 std::unique_ptr<ASTUnit> ErrUnit;
3107 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003108 Args->data(), Args->data() + Args->size(),
3109 CXXIdx->getPCHContainerOperations(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00003110 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
3111 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
3112 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
3113 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
3114 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
3115 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00003116
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003117 // Early failures in LoadFromCommandLine may return with ErrUnit unset.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003118 if (!Unit && !ErrUnit)
3119 return CXError_ASTReadError;
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003120
Guy Benyei11169dd2012-12-18 14:30:41 +00003121 if (NumErrors != Diags->getClient()->getNumErrors()) {
3122 // Make sure to check that 'Unit' is non-NULL.
3123 if (CXXIdx->getDisplayDiagnostics())
3124 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
3125 }
3126
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003127 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get()))
3128 return CXError_ASTReadError;
3129
3130 *out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
3131 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003132}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003133
3134CXTranslationUnit
3135clang_parseTranslationUnit(CXIndex CIdx,
3136 const char *source_filename,
3137 const char *const *command_line_args,
3138 int num_command_line_args,
3139 struct CXUnsavedFile *unsaved_files,
3140 unsigned num_unsaved_files,
3141 unsigned options) {
3142 CXTranslationUnit TU;
3143 enum CXErrorCode Result = clang_parseTranslationUnit2(
3144 CIdx, source_filename, command_line_args, num_command_line_args,
3145 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00003146 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003147 assert((TU && Result == CXError_Success) ||
3148 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003149 return TU;
3150}
3151
3152enum CXErrorCode clang_parseTranslationUnit2(
3153 CXIndex CIdx,
3154 const char *source_filename,
3155 const char *const *command_line_args,
3156 int num_command_line_args,
3157 struct CXUnsavedFile *unsaved_files,
3158 unsigned num_unsaved_files,
3159 unsigned options,
3160 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003161 LOG_FUNC_SECTION {
3162 *Log << source_filename << ": ";
3163 for (int i = 0; i != num_command_line_args; ++i)
3164 *Log << command_line_args[i] << " ";
3165 }
3166
Alp Toker9d85b182014-07-07 01:23:14 +00003167 if (num_unsaved_files && !unsaved_files)
3168 return CXError_InvalidArguments;
3169
Alp Toker5c532982014-07-07 22:42:03 +00003170 CXErrorCode result = CXError_Failure;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003171 auto ParseTranslationUnitImpl = [=, &result] {
3172 result = clang_parseTranslationUnit_Impl(
3173 CIdx, source_filename, command_line_args, num_command_line_args,
3174 llvm::makeArrayRef(unsaved_files, num_unsaved_files), options, out_TU);
3175 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003176 llvm::CrashRecoveryContext CRC;
3177
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003178 if (!RunSafely(CRC, ParseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003179 fprintf(stderr, "libclang: crash detected during parsing: {\n");
3180 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3181 fprintf(stderr, " 'command_line_args' : [");
3182 for (int i = 0; i != num_command_line_args; ++i) {
3183 if (i)
3184 fprintf(stderr, ", ");
3185 fprintf(stderr, "'%s'", command_line_args[i]);
3186 }
3187 fprintf(stderr, "],\n");
3188 fprintf(stderr, " 'unsaved_files' : [");
3189 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3190 if (i)
3191 fprintf(stderr, ", ");
3192 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3193 unsaved_files[i].Length);
3194 }
3195 fprintf(stderr, "],\n");
3196 fprintf(stderr, " 'options' : %d,\n", options);
3197 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003198
3199 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003200 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003201 if (CXTranslationUnit *TU = out_TU)
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003202 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003203 }
Alp Toker5c532982014-07-07 22:42:03 +00003204
3205 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003206}
3207
3208unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
3209 return CXSaveTranslationUnit_None;
3210}
3211
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003212static CXSaveError clang_saveTranslationUnit_Impl(CXTranslationUnit TU,
3213 const char *FileName,
3214 unsigned options) {
3215 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003216 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3217 setThreadBackgroundPriority();
3218
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003219 bool hadError = cxtu::getASTUnit(TU)->Save(FileName);
3220 return hadError ? CXSaveError_Unknown : CXSaveError_None;
Guy Benyei11169dd2012-12-18 14:30:41 +00003221}
3222
3223int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3224 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003225 LOG_FUNC_SECTION {
3226 *Log << TU << ' ' << FileName;
3227 }
3228
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003229 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003230 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003231 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003232 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003233
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003234 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003235 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3236 if (!CXXUnit->hasSema())
3237 return CXSaveError_InvalidTU;
3238
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003239 CXSaveError result;
3240 auto SaveTranslationUnitImpl = [=, &result]() {
3241 result = clang_saveTranslationUnit_Impl(TU, FileName, options);
3242 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003243
3244 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3245 getenv("LIBCLANG_NOTHREADS")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003246 SaveTranslationUnitImpl();
Guy Benyei11169dd2012-12-18 14:30:41 +00003247
3248 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3249 PrintLibclangResourceUsage(TU);
3250
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003251 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003252 }
3253
3254 // We have an AST that has invalid nodes due to compiler errors.
3255 // Use a crash recovery thread for protection.
3256
3257 llvm::CrashRecoveryContext CRC;
3258
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003259 if (!RunSafely(CRC, SaveTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003260 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3261 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3262 fprintf(stderr, " 'options' : %d,\n", options);
3263 fprintf(stderr, "}\n");
3264
3265 return CXSaveError_Unknown;
3266
3267 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3268 PrintLibclangResourceUsage(TU);
3269 }
3270
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003271 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003272}
3273
3274void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3275 if (CTUnit) {
3276 // If the translation unit has been marked as unsafe to free, just discard
3277 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003278 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3279 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003280 return;
3281
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003282 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003283 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003284 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3285 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003286 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003287 delete CTUnit;
3288 }
3289}
3290
3291unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3292 return CXReparse_None;
3293}
3294
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003295static CXErrorCode
3296clang_reparseTranslationUnit_Impl(CXTranslationUnit TU,
3297 ArrayRef<CXUnsavedFile> unsaved_files,
3298 unsigned options) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003299 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003300 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003301 LOG_BAD_TU(TU);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003302 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003303 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003304
3305 // Reset the associated diagnostics.
3306 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003307 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003308
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003309 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003310 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3311 setThreadBackgroundPriority();
3312
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003313 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003314 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003315
3316 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3317 new std::vector<ASTUnit::RemappedFile>());
3318
Guy Benyei11169dd2012-12-18 14:30:41 +00003319 // Recover resources if we crash before exiting this function.
3320 llvm::CrashRecoveryContextCleanupRegistrar<
3321 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003322
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003323 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003324 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003325 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003326 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003327 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003328
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003329 if (!CXXUnit->Reparse(CXXIdx->getPCHContainerOperations(),
3330 *RemappedFiles.get()))
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003331 return CXError_Success;
3332 if (isASTReadError(CXXUnit))
3333 return CXError_ASTReadError;
3334 return CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003335}
3336
3337int clang_reparseTranslationUnit(CXTranslationUnit TU,
3338 unsigned num_unsaved_files,
3339 struct CXUnsavedFile *unsaved_files,
3340 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003341 LOG_FUNC_SECTION {
3342 *Log << TU;
3343 }
3344
Alp Toker9d85b182014-07-07 01:23:14 +00003345 if (num_unsaved_files && !unsaved_files)
3346 return CXError_InvalidArguments;
3347
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003348 CXErrorCode result;
3349 auto ReparseTranslationUnitImpl = [=, &result]() {
3350 result = clang_reparseTranslationUnit_Impl(
3351 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options);
3352 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003353
3354 if (getenv("LIBCLANG_NOTHREADS")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003355 ReparseTranslationUnitImpl();
Alp Toker5c532982014-07-07 22:42:03 +00003356 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003357 }
3358
3359 llvm::CrashRecoveryContext CRC;
3360
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003361 if (!RunSafely(CRC, ReparseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003362 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003363 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003364 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003365 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3366 PrintLibclangResourceUsage(TU);
3367
Alp Toker5c532982014-07-07 22:42:03 +00003368 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003369}
3370
3371
3372CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003373 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003374 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003375 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003376 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003377
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003378 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003379 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003380}
3381
3382CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003383 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003384 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003385 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003386 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003387
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003388 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003389 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3390}
3391
3392} // end: extern "C"
3393
3394//===----------------------------------------------------------------------===//
3395// CXFile Operations.
3396//===----------------------------------------------------------------------===//
3397
3398extern "C" {
3399CXString clang_getFileName(CXFile SFile) {
3400 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003401 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003402
3403 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003404 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003405}
3406
3407time_t clang_getFileTime(CXFile SFile) {
3408 if (!SFile)
3409 return 0;
3410
3411 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3412 return FEnt->getModificationTime();
3413}
3414
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003415CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003416 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003417 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003418 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003419 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003420
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003421 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003422
3423 FileManager &FMgr = CXXUnit->getFileManager();
3424 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3425}
3426
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003427unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3428 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003429 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003430 LOG_BAD_TU(TU);
3431 return 0;
3432 }
3433
3434 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003435 return 0;
3436
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003437 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003438 FileEntry *FEnt = static_cast<FileEntry *>(file);
3439 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3440 .isFileMultipleIncludeGuarded(FEnt);
3441}
3442
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003443int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3444 if (!file || !outID)
3445 return 1;
3446
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003447 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003448 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3449 outID->data[0] = ID.getDevice();
3450 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003451 outID->data[2] = FEnt->getModificationTime();
3452 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003453}
3454
Argyrios Kyrtzidisac3997e2014-08-16 00:26:19 +00003455int clang_File_isEqual(CXFile file1, CXFile file2) {
3456 if (file1 == file2)
3457 return true;
3458
3459 if (!file1 || !file2)
3460 return false;
3461
3462 FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
3463 FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
3464 return FEnt1->getUniqueID() == FEnt2->getUniqueID();
3465}
3466
Guy Benyei11169dd2012-12-18 14:30:41 +00003467} // end: extern "C"
3468
3469//===----------------------------------------------------------------------===//
3470// CXCursor Operations.
3471//===----------------------------------------------------------------------===//
3472
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003473static const Decl *getDeclFromExpr(const Stmt *E) {
3474 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003475 return getDeclFromExpr(CE->getSubExpr());
3476
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003477 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003478 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003479 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003480 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003481 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003482 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003483 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003484 if (PRE->isExplicitProperty())
3485 return PRE->getExplicitProperty();
3486 // It could be messaging both getter and setter as in:
3487 // ++myobj.myprop;
3488 // in which case prefer to associate the setter since it is less obvious
3489 // from inspecting the source that the setter is going to get called.
3490 if (PRE->isMessagingSetter())
3491 return PRE->getImplicitPropertySetter();
3492 return PRE->getImplicitPropertyGetter();
3493 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003494 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003495 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003496 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003497 if (Expr *Src = OVE->getSourceExpr())
3498 return getDeclFromExpr(Src);
3499
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003500 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003501 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003502 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003503 if (!CE->isElidable())
3504 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003505 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003506 return OME->getMethodDecl();
3507
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003508 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003509 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003510 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003511 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3512 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003513 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003514 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3515 isa<ParmVarDecl>(SizeOfPack->getPack()))
3516 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003517
3518 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003519}
3520
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003521static SourceLocation getLocationFromExpr(const Expr *E) {
3522 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003523 return getLocationFromExpr(CE->getSubExpr());
3524
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003525 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003526 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003527 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003528 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003529 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003530 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003531 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003532 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003533 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003534 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003535 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003536 return PropRef->getLocation();
3537
3538 return E->getLocStart();
3539}
3540
Aaron Ballmana85d3f82015-11-12 15:25:06 +00003541static std::string getMangledStructor(std::unique_ptr<MangleContext> &M,
3542 std::unique_ptr<llvm::DataLayout> &DL,
3543 const NamedDecl *ND,
3544 unsigned StructorType) {
3545 std::string FrontendBuf;
3546 llvm::raw_string_ostream FOS(FrontendBuf);
3547
3548 if (const auto *CD = dyn_cast_or_null<CXXConstructorDecl>(ND))
3549 M->mangleCXXCtor(CD, static_cast<CXXCtorType>(StructorType), FOS);
3550 else if (const auto *DD = dyn_cast_or_null<CXXDestructorDecl>(ND))
3551 M->mangleCXXDtor(DD, static_cast<CXXDtorType>(StructorType), FOS);
3552
3553 std::string BackendBuf;
3554 llvm::raw_string_ostream BOS(BackendBuf);
3555
3556 llvm::Mangler::getNameWithPrefix(BOS, llvm::Twine(FOS.str()), *DL);
3557
3558 return BOS.str();
3559}
3560
Guy Benyei11169dd2012-12-18 14:30:41 +00003561extern "C" {
3562
3563unsigned clang_visitChildren(CXCursor parent,
3564 CXCursorVisitor visitor,
3565 CXClientData client_data) {
3566 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3567 /*VisitPreprocessorLast=*/false);
3568 return CursorVis.VisitChildren(parent);
3569}
3570
3571#ifndef __has_feature
3572#define __has_feature(x) 0
3573#endif
3574#if __has_feature(blocks)
3575typedef enum CXChildVisitResult
3576 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3577
3578static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3579 CXClientData client_data) {
3580 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3581 return block(cursor, parent);
3582}
3583#else
3584// If we are compiled with a compiler that doesn't have native blocks support,
3585// define and call the block manually, so the
3586typedef struct _CXChildVisitResult
3587{
3588 void *isa;
3589 int flags;
3590 int reserved;
3591 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3592 CXCursor);
3593} *CXCursorVisitorBlock;
3594
3595static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3596 CXClientData client_data) {
3597 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3598 return block->invoke(block, cursor, parent);
3599}
3600#endif
3601
3602
3603unsigned clang_visitChildrenWithBlock(CXCursor parent,
3604 CXCursorVisitorBlock block) {
3605 return clang_visitChildren(parent, visitWithBlock, block);
3606}
3607
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003608static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003609 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003610 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003611
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003612 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003613 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003614 if (const ObjCPropertyImplDecl *PropImpl =
3615 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003616 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003617 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003618
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003619 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003620 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003621 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003622
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003623 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003624 }
3625
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003626 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003627 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003628
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003629 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003630 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3631 // and returns different names. NamedDecl returns the class name and
3632 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003633 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003634
3635 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003636 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003637
3638 SmallString<1024> S;
3639 llvm::raw_svector_ostream os(S);
3640 ND->printName(os);
3641
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003642 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003643}
3644
3645CXString clang_getCursorSpelling(CXCursor C) {
3646 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003647 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003648
3649 if (clang_isReference(C.kind)) {
3650 switch (C.kind) {
3651 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003652 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003653 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003654 }
3655 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003656 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003657 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003658 }
3659 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003660 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003661 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003662 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003663 }
3664 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003665 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003666 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003667 }
3668 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003669 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003670 assert(Type && "Missing type decl");
3671
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003672 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003673 getAsString());
3674 }
3675 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003676 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003677 assert(Template && "Missing template decl");
3678
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003679 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003680 }
3681
3682 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003683 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003684 assert(NS && "Missing namespace decl");
3685
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003686 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003687 }
3688
3689 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003690 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003691 assert(Field && "Missing member decl");
3692
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003693 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003694 }
3695
3696 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003697 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003698 assert(Label && "Missing label");
3699
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003700 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003701 }
3702
3703 case CXCursor_OverloadedDeclRef: {
3704 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003705 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3706 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003707 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003708 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003709 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003710 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003711 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003712 OverloadedTemplateStorage *Ovl
3713 = Storage.get<OverloadedTemplateStorage*>();
3714 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003715 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003716 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003717 }
3718
3719 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003720 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003721 assert(Var && "Missing variable decl");
3722
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003723 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003724 }
3725
3726 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003727 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003728 }
3729 }
3730
3731 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003732 const Expr *E = getCursorExpr(C);
3733
3734 if (C.kind == CXCursor_ObjCStringLiteral ||
3735 C.kind == CXCursor_StringLiteral) {
3736 const StringLiteral *SLit;
3737 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3738 SLit = OSL->getString();
3739 } else {
3740 SLit = cast<StringLiteral>(E);
3741 }
3742 SmallString<256> Buf;
3743 llvm::raw_svector_ostream OS(Buf);
3744 SLit->outputString(OS);
3745 return cxstring::createDup(OS.str());
3746 }
3747
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003748 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003749 if (D)
3750 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003751 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003752 }
3753
3754 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003755 const Stmt *S = getCursorStmt(C);
3756 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003757 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003758
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003759 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003760 }
3761
3762 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003763 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003764 ->getNameStart());
3765
3766 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003767 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003768 ->getNameStart());
3769
3770 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003771 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003772
3773 if (clang_isDeclaration(C.kind))
3774 return getDeclSpelling(getCursorDecl(C));
3775
3776 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003777 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003778 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003779 }
3780
3781 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003782 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003783 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003784 }
3785
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003786 if (C.kind == CXCursor_PackedAttr) {
3787 return cxstring::createRef("packed");
3788 }
3789
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00003790 if (C.kind == CXCursor_VisibilityAttr) {
3791 const VisibilityAttr *AA = cast<VisibilityAttr>(cxcursor::getCursorAttr(C));
3792 switch (AA->getVisibility()) {
3793 case VisibilityAttr::VisibilityType::Default:
3794 return cxstring::createRef("default");
3795 case VisibilityAttr::VisibilityType::Hidden:
3796 return cxstring::createRef("hidden");
3797 case VisibilityAttr::VisibilityType::Protected:
3798 return cxstring::createRef("protected");
3799 }
3800 llvm_unreachable("unknown visibility type");
3801 }
3802
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003803 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003804}
3805
3806CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3807 unsigned pieceIndex,
3808 unsigned options) {
3809 if (clang_Cursor_isNull(C))
3810 return clang_getNullRange();
3811
3812 ASTContext &Ctx = getCursorContext(C);
3813
3814 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003815 const Stmt *S = getCursorStmt(C);
3816 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003817 if (pieceIndex > 0)
3818 return clang_getNullRange();
3819 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3820 }
3821
3822 return clang_getNullRange();
3823 }
3824
3825 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003826 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003827 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3828 if (pieceIndex >= ME->getNumSelectorLocs())
3829 return clang_getNullRange();
3830 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3831 }
3832 }
3833
3834 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3835 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003836 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003837 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3838 if (pieceIndex >= MD->getNumSelectorLocs())
3839 return clang_getNullRange();
3840 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3841 }
3842 }
3843
3844 if (C.kind == CXCursor_ObjCCategoryDecl ||
3845 C.kind == CXCursor_ObjCCategoryImplDecl) {
3846 if (pieceIndex > 0)
3847 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003848 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003849 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3850 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003851 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003852 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3853 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3854 }
3855
3856 if (C.kind == CXCursor_ModuleImportDecl) {
3857 if (pieceIndex > 0)
3858 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003859 if (const ImportDecl *ImportD =
3860 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003861 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3862 if (!Locs.empty())
3863 return cxloc::translateSourceRange(Ctx,
3864 SourceRange(Locs.front(), Locs.back()));
3865 }
3866 return clang_getNullRange();
3867 }
3868
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00003869 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
3870 C.kind == CXCursor_ConversionFunction) {
3871 if (pieceIndex > 0)
3872 return clang_getNullRange();
3873 if (const FunctionDecl *FD =
3874 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
3875 DeclarationNameInfo FunctionName = FD->getNameInfo();
3876 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
3877 }
3878 return clang_getNullRange();
3879 }
3880
Guy Benyei11169dd2012-12-18 14:30:41 +00003881 // FIXME: A CXCursor_InclusionDirective should give the location of the
3882 // filename, but we don't keep track of this.
3883
3884 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3885 // but we don't keep track of this.
3886
3887 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3888 // but we don't keep track of this.
3889
3890 // Default handling, give the location of the cursor.
3891
3892 if (pieceIndex > 0)
3893 return clang_getNullRange();
3894
3895 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3896 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3897 return cxloc::translateSourceRange(Ctx, Loc);
3898}
3899
Eli Bendersky44a206f2014-07-31 18:04:56 +00003900CXString clang_Cursor_getMangling(CXCursor C) {
3901 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
3902 return cxstring::createEmpty();
3903
Eli Bendersky44a206f2014-07-31 18:04:56 +00003904 // Mangling only works for functions and variables.
Eli Bendersky79759592014-08-01 15:01:10 +00003905 const Decl *D = getCursorDecl(C);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003906 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
3907 return cxstring::createEmpty();
3908
Eli Bendersky79759592014-08-01 15:01:10 +00003909 // First apply frontend mangling.
Eli Bendersky44a206f2014-07-31 18:04:56 +00003910 const NamedDecl *ND = cast<NamedDecl>(D);
Eli Bendersky79759592014-08-01 15:01:10 +00003911 ASTContext &Ctx = ND->getASTContext();
3912 std::unique_ptr<MangleContext> MC(Ctx.createMangleContext());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003913
Eli Bendersky79759592014-08-01 15:01:10 +00003914 std::string FrontendBuf;
3915 llvm::raw_string_ostream FrontendBufOS(FrontendBuf);
Ehsan Akhgarif8d44de2015-10-08 00:01:20 +00003916 if (MC->shouldMangleDeclName(ND)) {
3917 MC->mangleName(ND, FrontendBufOS);
3918 } else {
3919 ND->printName(FrontendBufOS);
3920 }
Eli Bendersky44a206f2014-07-31 18:04:56 +00003921
Eli Bendersky79759592014-08-01 15:01:10 +00003922 // Now apply backend mangling.
3923 std::unique_ptr<llvm::DataLayout> DL(
Eric Christopher964a5f32015-08-05 23:48:05 +00003924 new llvm::DataLayout(Ctx.getTargetInfo().getDataLayoutString()));
Eli Bendersky79759592014-08-01 15:01:10 +00003925
3926 std::string FinalBuf;
3927 llvm::raw_string_ostream FinalBufOS(FinalBuf);
Rafael Espindolab633d202015-06-23 13:59:36 +00003928 llvm::Mangler::getNameWithPrefix(FinalBufOS, llvm::Twine(FrontendBufOS.str()),
3929 *DL);
Eli Bendersky79759592014-08-01 15:01:10 +00003930
3931 return cxstring::createDup(FinalBufOS.str());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003932}
3933
Saleem Abdulrasool60034432015-11-12 03:57:22 +00003934CXStringSet *clang_Cursor_getCXXManglings(CXCursor C) {
3935 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
3936 return nullptr;
3937
3938 const Decl *D = getCursorDecl(C);
3939 if (!(isa<CXXRecordDecl>(D) || isa<CXXMethodDecl>(D)))
3940 return nullptr;
3941
3942 const NamedDecl *ND = cast<NamedDecl>(D);
3943
3944 ASTContext &Ctx = ND->getASTContext();
3945 std::unique_ptr<MangleContext> M(Ctx.createMangleContext());
3946 std::unique_ptr<llvm::DataLayout> DL(
3947 new llvm::DataLayout(Ctx.getTargetInfo().getDataLayoutString()));
3948
3949 std::vector<std::string> Manglings;
3950
3951 auto hasDefaultCXXMethodCC = [](ASTContext &C, const CXXMethodDecl *MD) {
3952 auto DefaultCC = C.getDefaultCallingConvention(/*IsVariadic=*/false,
3953 /*IsCSSMethod=*/true);
3954 auto CC = MD->getType()->getAs<FunctionProtoType>()->getCallConv();
3955 return CC == DefaultCC;
3956 };
3957
3958 if (const auto *CD = dyn_cast_or_null<CXXConstructorDecl>(ND)) {
3959 Manglings.emplace_back(getMangledStructor(M, DL, CD, Ctor_Base));
3960
3961 if (Ctx.getTargetInfo().getCXXABI().isItaniumFamily())
3962 if (!CD->getParent()->isAbstract())
3963 Manglings.emplace_back(getMangledStructor(M, DL, CD, Ctor_Complete));
3964
3965 if (Ctx.getTargetInfo().getCXXABI().isMicrosoft())
3966 if (CD->hasAttr<DLLExportAttr>() && CD->isDefaultConstructor())
3967 if (!(hasDefaultCXXMethodCC(Ctx, CD) && CD->getNumParams() == 0))
3968 Manglings.emplace_back(getMangledStructor(M, DL, CD,
3969 Ctor_DefaultClosure));
3970 } else if (const auto *DD = dyn_cast_or_null<CXXDestructorDecl>(ND)) {
3971 Manglings.emplace_back(getMangledStructor(M, DL, DD, Dtor_Base));
3972 if (Ctx.getTargetInfo().getCXXABI().isItaniumFamily()) {
3973 Manglings.emplace_back(getMangledStructor(M, DL, DD, Dtor_Complete));
3974
3975 if (!DD->isVirtual())
3976 Manglings.emplace_back(getMangledStructor(M, DL, DD, Dtor_Deleting));
3977 }
3978 }
3979
3980 return cxstring::createSet(Manglings);
3981}
3982
Guy Benyei11169dd2012-12-18 14:30:41 +00003983CXString clang_getCursorDisplayName(CXCursor C) {
3984 if (!clang_isDeclaration(C.kind))
3985 return clang_getCursorSpelling(C);
3986
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003987 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003988 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003989 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003990
3991 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003992 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003993 D = FunTmpl->getTemplatedDecl();
3994
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003995 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003996 SmallString<64> Str;
3997 llvm::raw_svector_ostream OS(Str);
3998 OS << *Function;
3999 if (Function->getPrimaryTemplate())
4000 OS << "<>";
4001 OS << "(";
4002 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
4003 if (I)
4004 OS << ", ";
4005 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
4006 }
4007
4008 if (Function->isVariadic()) {
4009 if (Function->getNumParams())
4010 OS << ", ";
4011 OS << "...";
4012 }
4013 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004014 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004015 }
4016
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004017 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004018 SmallString<64> Str;
4019 llvm::raw_svector_ostream OS(Str);
4020 OS << *ClassTemplate;
4021 OS << "<";
4022 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
4023 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
4024 if (I)
4025 OS << ", ";
4026
4027 NamedDecl *Param = Params->getParam(I);
4028 if (Param->getIdentifier()) {
4029 OS << Param->getIdentifier()->getName();
4030 continue;
4031 }
4032
4033 // There is no parameter name, which makes this tricky. Try to come up
4034 // with something useful that isn't too long.
4035 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
4036 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
4037 else if (NonTypeTemplateParmDecl *NTTP
4038 = dyn_cast<NonTypeTemplateParmDecl>(Param))
4039 OS << NTTP->getType().getAsString(Policy);
4040 else
4041 OS << "template<...> class";
4042 }
4043
4044 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004045 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004046 }
4047
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004048 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00004049 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
4050 // If the type was explicitly written, use that.
4051 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004052 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00004053
Benjamin Kramer9170e912013-02-22 15:46:01 +00004054 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00004055 llvm::raw_svector_ostream OS(Str);
4056 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00004057 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00004058 ClassSpec->getTemplateArgs().data(),
4059 ClassSpec->getTemplateArgs().size(),
4060 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004061 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004062 }
4063
4064 return clang_getCursorSpelling(C);
4065}
4066
4067CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
4068 switch (Kind) {
4069 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004070 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004071 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004072 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004073 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004074 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004075 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004076 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004077 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004078 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004079 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004080 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004081 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004082 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004083 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004084 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004085 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004086 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004087 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004088 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004089 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004090 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004091 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004092 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004093 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004094 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004095 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004096 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004097 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004098 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004099 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004100 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004101 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004102 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004103 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004104 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004105 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004106 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004107 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004108 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00004109 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004110 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004111 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004112 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004113 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004114 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004115 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004116 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004117 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004118 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004119 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004120 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004121 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004122 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004123 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004124 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004125 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004126 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004127 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004128 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004129 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004130 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004131 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004132 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004133 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004134 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004135 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004136 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004137 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004138 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004139 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004140 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004141 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004142 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004143 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004144 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004145 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004146 return cxstring::createRef("ArraySubscriptExpr");
Alexey Bataev1a3320e2015-08-25 14:24:04 +00004147 case CXCursor_OMPArraySectionExpr:
4148 return cxstring::createRef("OMPArraySectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004149 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004150 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004151 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004152 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004153 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004154 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004155 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004156 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004157 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004158 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004159 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004160 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004161 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004162 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004163 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004164 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004165 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004166 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004167 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004168 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004169 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004170 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004171 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004172 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004173 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004174 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004175 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004176 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004177 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004178 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004179 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004180 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004181 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004182 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004183 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004184 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004185 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004186 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004187 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004188 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004189 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004190 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004191 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004192 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004193 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004194 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004195 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004196 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004197 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004198 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00004199 case CXCursor_ObjCSelfExpr:
4200 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004201 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004202 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004203 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004204 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004205 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004206 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004207 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004208 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004209 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004210 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004211 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004212 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004213 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004214 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004215 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004216 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004217 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004218 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004219 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004220 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004221 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004222 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004223 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004224 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004225 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004226 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004227 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004228 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004229 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004230 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004231 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004232 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004233 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004234 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004235 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004236 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004237 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004238 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004239 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004240 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004241 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004242 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004243 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004244 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004245 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004246 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004247 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004248 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004249 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004250 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004251 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004252 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004253 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004254 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004255 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004256 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004257 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004258 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004259 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004260 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004261 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004262 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004263 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004264 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004265 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004266 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004267 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004268 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004269 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004270 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004271 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004272 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004273 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004274 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004275 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004276 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004277 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004278 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004279 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004280 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004281 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004282 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004283 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004284 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004285 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004286 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004287 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004288 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00004289 case CXCursor_SEHLeaveStmt:
4290 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004291 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004292 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004293 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004294 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00004295 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004296 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00004297 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004298 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00004299 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004300 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00004301 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004302 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00004303 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004304 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004305 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004306 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004307 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004308 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004309 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004310 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004311 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004312 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004313 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004314 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004315 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004316 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004317 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004318 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004319 case CXCursor_PackedAttr:
4320 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00004321 case CXCursor_PureAttr:
4322 return cxstring::createRef("attribute(pure)");
4323 case CXCursor_ConstAttr:
4324 return cxstring::createRef("attribute(const)");
4325 case CXCursor_NoDuplicateAttr:
4326 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00004327 case CXCursor_CUDAConstantAttr:
4328 return cxstring::createRef("attribute(constant)");
4329 case CXCursor_CUDADeviceAttr:
4330 return cxstring::createRef("attribute(device)");
4331 case CXCursor_CUDAGlobalAttr:
4332 return cxstring::createRef("attribute(global)");
4333 case CXCursor_CUDAHostAttr:
4334 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00004335 case CXCursor_CUDASharedAttr:
4336 return cxstring::createRef("attribute(shared)");
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00004337 case CXCursor_VisibilityAttr:
4338 return cxstring::createRef("attribute(visibility)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004339 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004340 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004341 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004342 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00004343 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004344 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004345 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004346 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004347 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004348 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00004349 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004350 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00004351 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004352 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004353 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004354 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004355 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004356 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004357 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004358 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004359 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004360 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004361 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004362 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004363 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004364 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004365 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004366 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004367 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004368 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004369 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004370 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004371 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004372 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004373 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004374 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004375 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004376 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004377 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004378 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004379 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004380 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004381 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004382 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004383 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004384 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004385 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004386 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004387 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004388 return cxstring::createRef("OMPParallelDirective");
4389 case CXCursor_OMPSimdDirective:
4390 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004391 case CXCursor_OMPForDirective:
4392 return cxstring::createRef("OMPForDirective");
Alexander Musmanf82886e2014-09-18 05:12:34 +00004393 case CXCursor_OMPForSimdDirective:
4394 return cxstring::createRef("OMPForSimdDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004395 case CXCursor_OMPSectionsDirective:
4396 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004397 case CXCursor_OMPSectionDirective:
4398 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004399 case CXCursor_OMPSingleDirective:
4400 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004401 case CXCursor_OMPMasterDirective:
4402 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004403 case CXCursor_OMPCriticalDirective:
4404 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004405 case CXCursor_OMPParallelForDirective:
4406 return cxstring::createRef("OMPParallelForDirective");
Alexander Musmane4e893b2014-09-23 09:33:00 +00004407 case CXCursor_OMPParallelForSimdDirective:
4408 return cxstring::createRef("OMPParallelForSimdDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004409 case CXCursor_OMPParallelSectionsDirective:
4410 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004411 case CXCursor_OMPTaskDirective:
4412 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004413 case CXCursor_OMPTaskyieldDirective:
4414 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004415 case CXCursor_OMPBarrierDirective:
4416 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004417 case CXCursor_OMPTaskwaitDirective:
4418 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00004419 case CXCursor_OMPTaskgroupDirective:
4420 return cxstring::createRef("OMPTaskgroupDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00004421 case CXCursor_OMPFlushDirective:
4422 return cxstring::createRef("OMPFlushDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004423 case CXCursor_OMPOrderedDirective:
4424 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00004425 case CXCursor_OMPAtomicDirective:
4426 return cxstring::createRef("OMPAtomicDirective");
Alexey Bataev0bd520b2014-09-19 08:19:49 +00004427 case CXCursor_OMPTargetDirective:
4428 return cxstring::createRef("OMPTargetDirective");
Michael Wong65f367f2015-07-21 13:44:28 +00004429 case CXCursor_OMPTargetDataDirective:
4430 return cxstring::createRef("OMPTargetDataDirective");
Alexey Bataev13314bf2014-10-09 04:18:56 +00004431 case CXCursor_OMPTeamsDirective:
4432 return cxstring::createRef("OMPTeamsDirective");
Alexey Bataev6d4ed052015-07-01 06:57:41 +00004433 case CXCursor_OMPCancellationPointDirective:
4434 return cxstring::createRef("OMPCancellationPointDirective");
Alexey Bataev80909872015-07-02 11:25:17 +00004435 case CXCursor_OMPCancelDirective:
4436 return cxstring::createRef("OMPCancelDirective");
Francisco Lopes da Silva975a9f62015-01-21 16:24:11 +00004437 case CXCursor_OverloadCandidate:
4438 return cxstring::createRef("OverloadCandidate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004439 }
4440
4441 llvm_unreachable("Unhandled CXCursorKind");
4442}
4443
4444struct GetCursorData {
4445 SourceLocation TokenBeginLoc;
4446 bool PointsAtMacroArgExpansion;
4447 bool VisitedObjCPropertyImplDecl;
4448 SourceLocation VisitedDeclaratorDeclStartLoc;
4449 CXCursor &BestCursor;
4450
4451 GetCursorData(SourceManager &SM,
4452 SourceLocation tokenBegin, CXCursor &outputCursor)
4453 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4454 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4455 VisitedObjCPropertyImplDecl = false;
4456 }
4457};
4458
4459static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4460 CXCursor parent,
4461 CXClientData client_data) {
4462 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4463 CXCursor *BestCursor = &Data->BestCursor;
4464
4465 // If we point inside a macro argument we should provide info of what the
4466 // token is so use the actual cursor, don't replace it with a macro expansion
4467 // cursor.
4468 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4469 return CXChildVisit_Recurse;
4470
4471 if (clang_isDeclaration(cursor.kind)) {
4472 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004473 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004474 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4475 if (MD->isImplicit())
4476 return CXChildVisit_Break;
4477
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004478 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004479 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4480 // Check that when we have multiple @class references in the same line,
4481 // that later ones do not override the previous ones.
4482 // If we have:
4483 // @class Foo, Bar;
4484 // source ranges for both start at '@', so 'Bar' will end up overriding
4485 // 'Foo' even though the cursor location was at 'Foo'.
4486 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4487 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004488 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004489 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4490 if (PrevID != ID &&
4491 !PrevID->isThisDeclarationADefinition() &&
4492 !ID->isThisDeclarationADefinition())
4493 return CXChildVisit_Break;
4494 }
4495
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004496 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004497 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4498 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4499 // Check that when we have multiple declarators in the same line,
4500 // that later ones do not override the previous ones.
4501 // If we have:
4502 // int Foo, Bar;
4503 // source ranges for both start at 'int', so 'Bar' will end up overriding
4504 // 'Foo' even though the cursor location was at 'Foo'.
4505 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4506 return CXChildVisit_Break;
4507 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4508
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004509 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004510 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4511 (void)PropImp;
4512 // Check that when we have multiple @synthesize in the same line,
4513 // that later ones do not override the previous ones.
4514 // If we have:
4515 // @synthesize Foo, Bar;
4516 // source ranges for both start at '@', so 'Bar' will end up overriding
4517 // 'Foo' even though the cursor location was at 'Foo'.
4518 if (Data->VisitedObjCPropertyImplDecl)
4519 return CXChildVisit_Break;
4520 Data->VisitedObjCPropertyImplDecl = true;
4521 }
4522 }
4523
4524 if (clang_isExpression(cursor.kind) &&
4525 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004526 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004527 // Avoid having the cursor of an expression replace the declaration cursor
4528 // when the expression source range overlaps the declaration range.
4529 // This can happen for C++ constructor expressions whose range generally
4530 // include the variable declaration, e.g.:
4531 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4532 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4533 D->getLocation() == Data->TokenBeginLoc)
4534 return CXChildVisit_Break;
4535 }
4536 }
4537
4538 // If our current best cursor is the construction of a temporary object,
4539 // don't replace that cursor with a type reference, because we want
4540 // clang_getCursor() to point at the constructor.
4541 if (clang_isExpression(BestCursor->kind) &&
4542 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4543 cursor.kind == CXCursor_TypeRef) {
4544 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4545 // as having the actual point on the type reference.
4546 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4547 return CXChildVisit_Recurse;
4548 }
Douglas Gregore9d95f12015-07-07 03:57:35 +00004549
4550 // If we already have an Objective-C superclass reference, don't
4551 // update it further.
4552 if (BestCursor->kind == CXCursor_ObjCSuperClassRef)
4553 return CXChildVisit_Break;
4554
Guy Benyei11169dd2012-12-18 14:30:41 +00004555 *BestCursor = cursor;
4556 return CXChildVisit_Recurse;
4557}
4558
4559CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004560 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004561 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004562 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004563 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004564
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004565 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004566 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4567
4568 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4569 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4570
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004571 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004572 CXFile SearchFile;
4573 unsigned SearchLine, SearchColumn;
4574 CXFile ResultFile;
4575 unsigned ResultLine, ResultColumn;
4576 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4577 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4578 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004579
4580 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4581 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004582 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004583 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004584 SearchFileName = clang_getFileName(SearchFile);
4585 ResultFileName = clang_getFileName(ResultFile);
4586 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4587 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004588 *Log << llvm::format("(%s:%d:%d) = %s",
4589 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4590 clang_getCString(KindSpelling))
4591 << llvm::format("(%s:%d:%d):%s%s",
4592 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4593 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004594 clang_disposeString(SearchFileName);
4595 clang_disposeString(ResultFileName);
4596 clang_disposeString(KindSpelling);
4597 clang_disposeString(USR);
4598
4599 CXCursor Definition = clang_getCursorDefinition(Result);
4600 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4601 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4602 CXString DefinitionKindSpelling
4603 = clang_getCursorKindSpelling(Definition.kind);
4604 CXFile DefinitionFile;
4605 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004606 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004607 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004608 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004609 *Log << llvm::format(" -> %s(%s:%d:%d)",
4610 clang_getCString(DefinitionKindSpelling),
4611 clang_getCString(DefinitionFileName),
4612 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004613 clang_disposeString(DefinitionFileName);
4614 clang_disposeString(DefinitionKindSpelling);
4615 }
4616 }
4617
4618 return Result;
4619}
4620
4621CXCursor clang_getNullCursor(void) {
4622 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4623}
4624
4625unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004626 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4627 // can't set consistently. For example, when visiting a DeclStmt we will set
4628 // it but we don't set it on the result of clang_getCursorDefinition for
4629 // a reference of the same declaration.
4630 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4631 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4632 // to provide that kind of info.
4633 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004634 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004635 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004636 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004637
Guy Benyei11169dd2012-12-18 14:30:41 +00004638 return X == Y;
4639}
4640
4641unsigned clang_hashCursor(CXCursor C) {
4642 unsigned Index = 0;
4643 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4644 Index = 1;
4645
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004646 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004647 std::make_pair(C.kind, C.data[Index]));
4648}
4649
4650unsigned clang_isInvalid(enum CXCursorKind K) {
4651 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4652}
4653
4654unsigned clang_isDeclaration(enum CXCursorKind K) {
4655 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4656 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4657}
4658
4659unsigned clang_isReference(enum CXCursorKind K) {
4660 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4661}
4662
4663unsigned clang_isExpression(enum CXCursorKind K) {
4664 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4665}
4666
4667unsigned clang_isStatement(enum CXCursorKind K) {
4668 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4669}
4670
4671unsigned clang_isAttribute(enum CXCursorKind K) {
4672 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4673}
4674
4675unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4676 return K == CXCursor_TranslationUnit;
4677}
4678
4679unsigned clang_isPreprocessing(enum CXCursorKind K) {
4680 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4681}
4682
4683unsigned clang_isUnexposed(enum CXCursorKind K) {
4684 switch (K) {
4685 case CXCursor_UnexposedDecl:
4686 case CXCursor_UnexposedExpr:
4687 case CXCursor_UnexposedStmt:
4688 case CXCursor_UnexposedAttr:
4689 return true;
4690 default:
4691 return false;
4692 }
4693}
4694
4695CXCursorKind clang_getCursorKind(CXCursor C) {
4696 return C.kind;
4697}
4698
4699CXSourceLocation clang_getCursorLocation(CXCursor C) {
4700 if (clang_isReference(C.kind)) {
4701 switch (C.kind) {
4702 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004703 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004704 = getCursorObjCSuperClassRef(C);
4705 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4706 }
4707
4708 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004709 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004710 = getCursorObjCProtocolRef(C);
4711 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4712 }
4713
4714 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004715 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004716 = getCursorObjCClassRef(C);
4717 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4718 }
4719
4720 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004721 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004722 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4723 }
4724
4725 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004726 std::pair<const TemplateDecl *, SourceLocation> P =
4727 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004728 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4729 }
4730
4731 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004732 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004733 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4734 }
4735
4736 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004737 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004738 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4739 }
4740
4741 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004742 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004743 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4744 }
4745
4746 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004747 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004748 if (!BaseSpec)
4749 return clang_getNullLocation();
4750
4751 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4752 return cxloc::translateSourceLocation(getCursorContext(C),
4753 TSInfo->getTypeLoc().getBeginLoc());
4754
4755 return cxloc::translateSourceLocation(getCursorContext(C),
4756 BaseSpec->getLocStart());
4757 }
4758
4759 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004760 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004761 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4762 }
4763
4764 case CXCursor_OverloadedDeclRef:
4765 return cxloc::translateSourceLocation(getCursorContext(C),
4766 getCursorOverloadedDeclRef(C).second);
4767
4768 default:
4769 // FIXME: Need a way to enumerate all non-reference cases.
4770 llvm_unreachable("Missed a reference kind");
4771 }
4772 }
4773
4774 if (clang_isExpression(C.kind))
4775 return cxloc::translateSourceLocation(getCursorContext(C),
4776 getLocationFromExpr(getCursorExpr(C)));
4777
4778 if (clang_isStatement(C.kind))
4779 return cxloc::translateSourceLocation(getCursorContext(C),
4780 getCursorStmt(C)->getLocStart());
4781
4782 if (C.kind == CXCursor_PreprocessingDirective) {
4783 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4784 return cxloc::translateSourceLocation(getCursorContext(C), L);
4785 }
4786
4787 if (C.kind == CXCursor_MacroExpansion) {
4788 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004789 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004790 return cxloc::translateSourceLocation(getCursorContext(C), L);
4791 }
4792
4793 if (C.kind == CXCursor_MacroDefinition) {
4794 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4795 return cxloc::translateSourceLocation(getCursorContext(C), L);
4796 }
4797
4798 if (C.kind == CXCursor_InclusionDirective) {
4799 SourceLocation L
4800 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4801 return cxloc::translateSourceLocation(getCursorContext(C), L);
4802 }
4803
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004804 if (clang_isAttribute(C.kind)) {
4805 SourceLocation L
4806 = cxcursor::getCursorAttr(C)->getLocation();
4807 return cxloc::translateSourceLocation(getCursorContext(C), L);
4808 }
4809
Guy Benyei11169dd2012-12-18 14:30:41 +00004810 if (!clang_isDeclaration(C.kind))
4811 return clang_getNullLocation();
4812
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004813 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004814 if (!D)
4815 return clang_getNullLocation();
4816
4817 SourceLocation Loc = D->getLocation();
4818 // FIXME: Multiple variables declared in a single declaration
4819 // currently lack the information needed to correctly determine their
4820 // ranges when accounting for the type-specifier. We use context
4821 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4822 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004823 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004824 if (!cxcursor::isFirstInDeclGroup(C))
4825 Loc = VD->getLocation();
4826 }
4827
4828 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004829 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004830 Loc = MD->getSelectorStartLoc();
4831
4832 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4833}
4834
4835} // end extern "C"
4836
4837CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4838 assert(TU);
4839
4840 // Guard against an invalid SourceLocation, or we may assert in one
4841 // of the following calls.
4842 if (SLoc.isInvalid())
4843 return clang_getNullCursor();
4844
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004845 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004846
4847 // Translate the given source location to make it point at the beginning of
4848 // the token under the cursor.
4849 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4850 CXXUnit->getASTContext().getLangOpts());
4851
4852 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4853 if (SLoc.isValid()) {
4854 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4855 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4856 /*VisitPreprocessorLast=*/true,
4857 /*VisitIncludedEntities=*/false,
4858 SourceLocation(SLoc));
4859 CursorVis.visitFileRegion();
4860 }
4861
4862 return Result;
4863}
4864
4865static SourceRange getRawCursorExtent(CXCursor C) {
4866 if (clang_isReference(C.kind)) {
4867 switch (C.kind) {
4868 case CXCursor_ObjCSuperClassRef:
4869 return getCursorObjCSuperClassRef(C).second;
4870
4871 case CXCursor_ObjCProtocolRef:
4872 return getCursorObjCProtocolRef(C).second;
4873
4874 case CXCursor_ObjCClassRef:
4875 return getCursorObjCClassRef(C).second;
4876
4877 case CXCursor_TypeRef:
4878 return getCursorTypeRef(C).second;
4879
4880 case CXCursor_TemplateRef:
4881 return getCursorTemplateRef(C).second;
4882
4883 case CXCursor_NamespaceRef:
4884 return getCursorNamespaceRef(C).second;
4885
4886 case CXCursor_MemberRef:
4887 return getCursorMemberRef(C).second;
4888
4889 case CXCursor_CXXBaseSpecifier:
4890 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4891
4892 case CXCursor_LabelRef:
4893 return getCursorLabelRef(C).second;
4894
4895 case CXCursor_OverloadedDeclRef:
4896 return getCursorOverloadedDeclRef(C).second;
4897
4898 case CXCursor_VariableRef:
4899 return getCursorVariableRef(C).second;
4900
4901 default:
4902 // FIXME: Need a way to enumerate all non-reference cases.
4903 llvm_unreachable("Missed a reference kind");
4904 }
4905 }
4906
4907 if (clang_isExpression(C.kind))
4908 return getCursorExpr(C)->getSourceRange();
4909
4910 if (clang_isStatement(C.kind))
4911 return getCursorStmt(C)->getSourceRange();
4912
4913 if (clang_isAttribute(C.kind))
4914 return getCursorAttr(C)->getRange();
4915
4916 if (C.kind == CXCursor_PreprocessingDirective)
4917 return cxcursor::getCursorPreprocessingDirective(C);
4918
4919 if (C.kind == CXCursor_MacroExpansion) {
4920 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004921 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004922 return TU->mapRangeFromPreamble(Range);
4923 }
4924
4925 if (C.kind == CXCursor_MacroDefinition) {
4926 ASTUnit *TU = getCursorASTUnit(C);
4927 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4928 return TU->mapRangeFromPreamble(Range);
4929 }
4930
4931 if (C.kind == CXCursor_InclusionDirective) {
4932 ASTUnit *TU = getCursorASTUnit(C);
4933 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4934 return TU->mapRangeFromPreamble(Range);
4935 }
4936
4937 if (C.kind == CXCursor_TranslationUnit) {
4938 ASTUnit *TU = getCursorASTUnit(C);
4939 FileID MainID = TU->getSourceManager().getMainFileID();
4940 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4941 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4942 return SourceRange(Start, End);
4943 }
4944
4945 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004946 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004947 if (!D)
4948 return SourceRange();
4949
4950 SourceRange R = D->getSourceRange();
4951 // FIXME: Multiple variables declared in a single declaration
4952 // currently lack the information needed to correctly determine their
4953 // ranges when accounting for the type-specifier. We use context
4954 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4955 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004956 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004957 if (!cxcursor::isFirstInDeclGroup(C))
4958 R.setBegin(VD->getLocation());
4959 }
4960 return R;
4961 }
4962 return SourceRange();
4963}
4964
4965/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4966/// the decl-specifier-seq for declarations.
4967static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4968 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004969 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004970 if (!D)
4971 return SourceRange();
4972
4973 SourceRange R = D->getSourceRange();
4974
4975 // Adjust the start of the location for declarations preceded by
4976 // declaration specifiers.
4977 SourceLocation StartLoc;
4978 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4979 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4980 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004981 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004982 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4983 StartLoc = TI->getTypeLoc().getLocStart();
4984 }
4985
4986 if (StartLoc.isValid() && R.getBegin().isValid() &&
4987 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4988 R.setBegin(StartLoc);
4989
4990 // FIXME: Multiple variables declared in a single declaration
4991 // currently lack the information needed to correctly determine their
4992 // ranges when accounting for the type-specifier. We use context
4993 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4994 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004995 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004996 if (!cxcursor::isFirstInDeclGroup(C))
4997 R.setBegin(VD->getLocation());
4998 }
4999
5000 return R;
5001 }
5002
5003 return getRawCursorExtent(C);
5004}
5005
5006extern "C" {
5007
5008CXSourceRange clang_getCursorExtent(CXCursor C) {
5009 SourceRange R = getRawCursorExtent(C);
5010 if (R.isInvalid())
5011 return clang_getNullRange();
5012
5013 return cxloc::translateSourceRange(getCursorContext(C), R);
5014}
5015
5016CXCursor clang_getCursorReferenced(CXCursor C) {
5017 if (clang_isInvalid(C.kind))
5018 return clang_getNullCursor();
5019
5020 CXTranslationUnit tu = getCursorTU(C);
5021 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005022 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005023 if (!D)
5024 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005025 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005026 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005027 if (const ObjCPropertyImplDecl *PropImpl =
5028 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005029 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
5030 return MakeCXCursor(Property, tu);
5031
5032 return C;
5033 }
5034
5035 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005036 const Expr *E = getCursorExpr(C);
5037 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00005038 if (D) {
5039 CXCursor declCursor = MakeCXCursor(D, tu);
5040 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
5041 declCursor);
5042 return declCursor;
5043 }
5044
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005045 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00005046 return MakeCursorOverloadedDeclRef(Ovl, tu);
5047
5048 return clang_getNullCursor();
5049 }
5050
5051 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005052 const Stmt *S = getCursorStmt(C);
5053 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00005054 if (LabelDecl *label = Goto->getLabel())
5055 if (LabelStmt *labelS = label->getStmt())
5056 return MakeCXCursor(labelS, getCursorDecl(C), tu);
5057
5058 return clang_getNullCursor();
5059 }
Richard Smith66a81862015-05-04 02:25:31 +00005060
Guy Benyei11169dd2012-12-18 14:30:41 +00005061 if (C.kind == CXCursor_MacroExpansion) {
Richard Smith66a81862015-05-04 02:25:31 +00005062 if (const MacroDefinitionRecord *Def =
5063 getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005064 return MakeMacroDefinitionCursor(Def, tu);
5065 }
5066
5067 if (!clang_isReference(C.kind))
5068 return clang_getNullCursor();
5069
5070 switch (C.kind) {
5071 case CXCursor_ObjCSuperClassRef:
5072 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
5073
5074 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005075 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
5076 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005077 return MakeCXCursor(Def, tu);
5078
5079 return MakeCXCursor(Prot, tu);
5080 }
5081
5082 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005083 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
5084 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005085 return MakeCXCursor(Def, tu);
5086
5087 return MakeCXCursor(Class, tu);
5088 }
5089
5090 case CXCursor_TypeRef:
5091 return MakeCXCursor(getCursorTypeRef(C).first, tu );
5092
5093 case CXCursor_TemplateRef:
5094 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
5095
5096 case CXCursor_NamespaceRef:
5097 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
5098
5099 case CXCursor_MemberRef:
5100 return MakeCXCursor(getCursorMemberRef(C).first, tu );
5101
5102 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005103 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005104 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
5105 tu ));
5106 }
5107
5108 case CXCursor_LabelRef:
5109 // FIXME: We end up faking the "parent" declaration here because we
5110 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005111 return MakeCXCursor(getCursorLabelRef(C).first,
5112 cxtu::getASTUnit(tu)->getASTContext()
5113 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00005114 tu);
5115
5116 case CXCursor_OverloadedDeclRef:
5117 return C;
5118
5119 case CXCursor_VariableRef:
5120 return MakeCXCursor(getCursorVariableRef(C).first, tu);
5121
5122 default:
5123 // We would prefer to enumerate all non-reference cursor kinds here.
5124 llvm_unreachable("Unhandled reference cursor kind");
5125 }
5126}
5127
5128CXCursor clang_getCursorDefinition(CXCursor C) {
5129 if (clang_isInvalid(C.kind))
5130 return clang_getNullCursor();
5131
5132 CXTranslationUnit TU = getCursorTU(C);
5133
5134 bool WasReference = false;
5135 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
5136 C = clang_getCursorReferenced(C);
5137 WasReference = true;
5138 }
5139
5140 if (C.kind == CXCursor_MacroExpansion)
5141 return clang_getCursorReferenced(C);
5142
5143 if (!clang_isDeclaration(C.kind))
5144 return clang_getNullCursor();
5145
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005146 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005147 if (!D)
5148 return clang_getNullCursor();
5149
5150 switch (D->getKind()) {
5151 // Declaration kinds that don't really separate the notions of
5152 // declaration and definition.
5153 case Decl::Namespace:
5154 case Decl::Typedef:
5155 case Decl::TypeAlias:
5156 case Decl::TypeAliasTemplate:
5157 case Decl::TemplateTypeParm:
5158 case Decl::EnumConstant:
5159 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00005160 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005161 case Decl::IndirectField:
5162 case Decl::ObjCIvar:
5163 case Decl::ObjCAtDefsField:
5164 case Decl::ImplicitParam:
5165 case Decl::ParmVar:
5166 case Decl::NonTypeTemplateParm:
5167 case Decl::TemplateTemplateParm:
5168 case Decl::ObjCCategoryImpl:
5169 case Decl::ObjCImplementation:
5170 case Decl::AccessSpec:
5171 case Decl::LinkageSpec:
5172 case Decl::ObjCPropertyImpl:
5173 case Decl::FileScopeAsm:
5174 case Decl::StaticAssert:
5175 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00005176 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00005177 case Decl::Label: // FIXME: Is this right??
5178 case Decl::ClassScopeFunctionSpecialization:
5179 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00005180 case Decl::OMPThreadPrivate:
Douglas Gregor85f3f952015-07-07 03:57:15 +00005181 case Decl::ObjCTypeParam:
David Majnemerd9b1a4f2015-11-04 03:40:30 +00005182 case Decl::BuiltinTemplate:
Guy Benyei11169dd2012-12-18 14:30:41 +00005183 return C;
5184
5185 // Declaration kinds that don't make any sense here, but are
5186 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00005187 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005188 case Decl::TranslationUnit:
Richard Smithf19e1272015-03-07 00:04:49 +00005189 case Decl::ExternCContext:
Guy Benyei11169dd2012-12-18 14:30:41 +00005190 break;
5191
5192 // Declaration kinds for which the definition is not resolvable.
5193 case Decl::UnresolvedUsingTypename:
5194 case Decl::UnresolvedUsingValue:
5195 break;
5196
5197 case Decl::UsingDirective:
5198 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
5199 TU);
5200
5201 case Decl::NamespaceAlias:
5202 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
5203
5204 case Decl::Enum:
5205 case Decl::Record:
5206 case Decl::CXXRecord:
5207 case Decl::ClassTemplateSpecialization:
5208 case Decl::ClassTemplatePartialSpecialization:
5209 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
5210 return MakeCXCursor(Def, TU);
5211 return clang_getNullCursor();
5212
5213 case Decl::Function:
5214 case Decl::CXXMethod:
5215 case Decl::CXXConstructor:
5216 case Decl::CXXDestructor:
5217 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00005218 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005219 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00005220 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005221 return clang_getNullCursor();
5222 }
5223
Larisse Voufo39a1e502013-08-06 01:03:05 +00005224 case Decl::Var:
5225 case Decl::VarTemplateSpecialization:
5226 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00005227 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005228 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005229 return MakeCXCursor(Def, TU);
5230 return clang_getNullCursor();
5231 }
5232
5233 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00005234 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005235 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
5236 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
5237 return clang_getNullCursor();
5238 }
5239
5240 case Decl::ClassTemplate: {
5241 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
5242 ->getDefinition())
5243 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
5244 TU);
5245 return clang_getNullCursor();
5246 }
5247
Larisse Voufo39a1e502013-08-06 01:03:05 +00005248 case Decl::VarTemplate: {
5249 if (VarDecl *Def =
5250 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
5251 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
5252 return clang_getNullCursor();
5253 }
5254
Guy Benyei11169dd2012-12-18 14:30:41 +00005255 case Decl::Using:
5256 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
5257 D->getLocation(), TU);
5258
5259 case Decl::UsingShadow:
5260 return clang_getCursorDefinition(
5261 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
5262 TU));
5263
5264 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005265 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005266 if (Method->isThisDeclarationADefinition())
5267 return C;
5268
5269 // Dig out the method definition in the associated
5270 // @implementation, if we have it.
5271 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005272 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005273 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
5274 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
5275 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
5276 Method->isInstanceMethod()))
5277 if (Def->isThisDeclarationADefinition())
5278 return MakeCXCursor(Def, TU);
5279
5280 return clang_getNullCursor();
5281 }
5282
5283 case Decl::ObjCCategory:
5284 if (ObjCCategoryImplDecl *Impl
5285 = cast<ObjCCategoryDecl>(D)->getImplementation())
5286 return MakeCXCursor(Impl, TU);
5287 return clang_getNullCursor();
5288
5289 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005290 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005291 return MakeCXCursor(Def, TU);
5292 return clang_getNullCursor();
5293
5294 case Decl::ObjCInterface: {
5295 // There are two notions of a "definition" for an Objective-C
5296 // class: the interface and its implementation. When we resolved a
5297 // reference to an Objective-C class, produce the @interface as
5298 // the definition; when we were provided with the interface,
5299 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005300 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005301 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005302 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005303 return MakeCXCursor(Def, TU);
5304 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
5305 return MakeCXCursor(Impl, TU);
5306 return clang_getNullCursor();
5307 }
5308
5309 case Decl::ObjCProperty:
5310 // FIXME: We don't really know where to find the
5311 // ObjCPropertyImplDecls that implement this property.
5312 return clang_getNullCursor();
5313
5314 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005315 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005316 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005317 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005318 return MakeCXCursor(Def, TU);
5319
5320 return clang_getNullCursor();
5321
5322 case Decl::Friend:
5323 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
5324 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5325 return clang_getNullCursor();
5326
5327 case Decl::FriendTemplate:
5328 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
5329 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5330 return clang_getNullCursor();
5331 }
5332
5333 return clang_getNullCursor();
5334}
5335
5336unsigned clang_isCursorDefinition(CXCursor C) {
5337 if (!clang_isDeclaration(C.kind))
5338 return 0;
5339
5340 return clang_getCursorDefinition(C) == C;
5341}
5342
5343CXCursor clang_getCanonicalCursor(CXCursor C) {
5344 if (!clang_isDeclaration(C.kind))
5345 return C;
5346
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005347 if (const Decl *D = getCursorDecl(C)) {
5348 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005349 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5350 return MakeCXCursor(CatD, getCursorTU(C));
5351
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005352 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5353 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00005354 return MakeCXCursor(IFD, getCursorTU(C));
5355
5356 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5357 }
5358
5359 return C;
5360}
5361
5362int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5363 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5364}
5365
5366unsigned clang_getNumOverloadedDecls(CXCursor C) {
5367 if (C.kind != CXCursor_OverloadedDeclRef)
5368 return 0;
5369
5370 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005371 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005372 return E->getNumDecls();
5373
5374 if (OverloadedTemplateStorage *S
5375 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5376 return S->size();
5377
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005378 const Decl *D = Storage.get<const Decl *>();
5379 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005380 return Using->shadow_size();
5381
5382 return 0;
5383}
5384
5385CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5386 if (cursor.kind != CXCursor_OverloadedDeclRef)
5387 return clang_getNullCursor();
5388
5389 if (index >= clang_getNumOverloadedDecls(cursor))
5390 return clang_getNullCursor();
5391
5392 CXTranslationUnit TU = getCursorTU(cursor);
5393 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005394 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005395 return MakeCXCursor(E->decls_begin()[index], TU);
5396
5397 if (OverloadedTemplateStorage *S
5398 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5399 return MakeCXCursor(S->begin()[index], TU);
5400
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005401 const Decl *D = Storage.get<const Decl *>();
5402 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005403 // FIXME: This is, unfortunately, linear time.
5404 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5405 std::advance(Pos, index);
5406 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5407 }
5408
5409 return clang_getNullCursor();
5410}
5411
5412void clang_getDefinitionSpellingAndExtent(CXCursor C,
5413 const char **startBuf,
5414 const char **endBuf,
5415 unsigned *startLine,
5416 unsigned *startColumn,
5417 unsigned *endLine,
5418 unsigned *endColumn) {
5419 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005420 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005421 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5422
5423 SourceManager &SM = FD->getASTContext().getSourceManager();
5424 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5425 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5426 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5427 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5428 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5429 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5430}
5431
5432
5433CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5434 unsigned PieceIndex) {
5435 RefNamePieces Pieces;
5436
5437 switch (C.kind) {
5438 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005439 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005440 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5441 E->getQualifierLoc().getSourceRange());
5442 break;
5443
5444 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005445 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005446 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
5447 E->getQualifierLoc().getSourceRange(),
5448 E->getOptionalExplicitTemplateArgs());
5449 break;
5450
5451 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005452 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005453 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005454 const Expr *Callee = OCE->getCallee();
5455 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005456 Callee = ICE->getSubExpr();
5457
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005458 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005459 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5460 DRE->getQualifierLoc().getSourceRange());
5461 }
5462 break;
5463
5464 default:
5465 break;
5466 }
5467
5468 if (Pieces.empty()) {
5469 if (PieceIndex == 0)
5470 return clang_getCursorExtent(C);
5471 } else if (PieceIndex < Pieces.size()) {
5472 SourceRange R = Pieces[PieceIndex];
5473 if (R.isValid())
5474 return cxloc::translateSourceRange(getCursorContext(C), R);
5475 }
5476
5477 return clang_getNullRange();
5478}
5479
5480void clang_enableStackTraces(void) {
5481 llvm::sys::PrintStackTraceOnErrorSignal();
5482}
5483
5484void clang_executeOnThread(void (*fn)(void*), void *user_data,
5485 unsigned stack_size) {
5486 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5487}
5488
5489} // end: extern "C"
5490
5491//===----------------------------------------------------------------------===//
5492// Token-based Operations.
5493//===----------------------------------------------------------------------===//
5494
5495/* CXToken layout:
5496 * int_data[0]: a CXTokenKind
5497 * int_data[1]: starting token location
5498 * int_data[2]: token length
5499 * int_data[3]: reserved
5500 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5501 * otherwise unused.
5502 */
5503extern "C" {
5504
5505CXTokenKind clang_getTokenKind(CXToken CXTok) {
5506 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5507}
5508
5509CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5510 switch (clang_getTokenKind(CXTok)) {
5511 case CXToken_Identifier:
5512 case CXToken_Keyword:
5513 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005514 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005515 ->getNameStart());
5516
5517 case CXToken_Literal: {
5518 // We have stashed the starting pointer in the ptr_data field. Use it.
5519 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005520 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005521 }
5522
5523 case CXToken_Punctuation:
5524 case CXToken_Comment:
5525 break;
5526 }
5527
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005528 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005529 LOG_BAD_TU(TU);
5530 return cxstring::createEmpty();
5531 }
5532
Guy Benyei11169dd2012-12-18 14:30:41 +00005533 // We have to find the starting buffer pointer the hard way, by
5534 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005535 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005536 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005537 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005538
5539 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5540 std::pair<FileID, unsigned> LocInfo
5541 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5542 bool Invalid = false;
5543 StringRef Buffer
5544 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5545 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005546 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005547
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005548 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005549}
5550
5551CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005552 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005553 LOG_BAD_TU(TU);
5554 return clang_getNullLocation();
5555 }
5556
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005557 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005558 if (!CXXUnit)
5559 return clang_getNullLocation();
5560
5561 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5562 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5563}
5564
5565CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005566 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005567 LOG_BAD_TU(TU);
5568 return clang_getNullRange();
5569 }
5570
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005571 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005572 if (!CXXUnit)
5573 return clang_getNullRange();
5574
5575 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5576 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5577}
5578
5579static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5580 SmallVectorImpl<CXToken> &CXTokens) {
5581 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5582 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005583 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005584 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005585 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005586
5587 // Cannot tokenize across files.
5588 if (BeginLocInfo.first != EndLocInfo.first)
5589 return;
5590
5591 // Create a lexer
5592 bool Invalid = false;
5593 StringRef Buffer
5594 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5595 if (Invalid)
5596 return;
5597
5598 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5599 CXXUnit->getASTContext().getLangOpts(),
5600 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5601 Lex.SetCommentRetentionState(true);
5602
5603 // Lex tokens until we hit the end of the range.
5604 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5605 Token Tok;
5606 bool previousWasAt = false;
5607 do {
5608 // Lex the next token
5609 Lex.LexFromRawLexer(Tok);
5610 if (Tok.is(tok::eof))
5611 break;
5612
5613 // Initialize the CXToken.
5614 CXToken CXTok;
5615
5616 // - Common fields
5617 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5618 CXTok.int_data[2] = Tok.getLength();
5619 CXTok.int_data[3] = 0;
5620
5621 // - Kind-specific fields
5622 if (Tok.isLiteral()) {
5623 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005624 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005625 } else if (Tok.is(tok::raw_identifier)) {
5626 // Lookup the identifier to determine whether we have a keyword.
5627 IdentifierInfo *II
5628 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5629
5630 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5631 CXTok.int_data[0] = CXToken_Keyword;
5632 }
5633 else {
5634 CXTok.int_data[0] = Tok.is(tok::identifier)
5635 ? CXToken_Identifier
5636 : CXToken_Keyword;
5637 }
5638 CXTok.ptr_data = II;
5639 } else if (Tok.is(tok::comment)) {
5640 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005641 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005642 } else {
5643 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005644 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005645 }
5646 CXTokens.push_back(CXTok);
5647 previousWasAt = Tok.is(tok::at);
5648 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5649}
5650
5651void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5652 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005653 LOG_FUNC_SECTION {
5654 *Log << TU << ' ' << Range;
5655 }
5656
Guy Benyei11169dd2012-12-18 14:30:41 +00005657 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005658 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005659 if (NumTokens)
5660 *NumTokens = 0;
5661
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005662 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005663 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005664 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005665 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005666
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005667 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005668 if (!CXXUnit || !Tokens || !NumTokens)
5669 return;
5670
5671 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5672
5673 SourceRange R = cxloc::translateCXSourceRange(Range);
5674 if (R.isInvalid())
5675 return;
5676
5677 SmallVector<CXToken, 32> CXTokens;
5678 getTokens(CXXUnit, R, CXTokens);
5679
5680 if (CXTokens.empty())
5681 return;
5682
5683 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5684 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5685 *NumTokens = CXTokens.size();
5686}
5687
5688void clang_disposeTokens(CXTranslationUnit TU,
5689 CXToken *Tokens, unsigned NumTokens) {
5690 free(Tokens);
5691}
5692
5693} // end: extern "C"
5694
5695//===----------------------------------------------------------------------===//
5696// Token annotation APIs.
5697//===----------------------------------------------------------------------===//
5698
Guy Benyei11169dd2012-12-18 14:30:41 +00005699static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5700 CXCursor parent,
5701 CXClientData client_data);
5702static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5703 CXClientData client_data);
5704
5705namespace {
5706class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005707 CXToken *Tokens;
5708 CXCursor *Cursors;
5709 unsigned NumTokens;
5710 unsigned TokIdx;
5711 unsigned PreprocessingTokIdx;
5712 CursorVisitor AnnotateVis;
5713 SourceManager &SrcMgr;
5714 bool HasContextSensitiveKeywords;
5715
5716 struct PostChildrenInfo {
5717 CXCursor Cursor;
5718 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005719 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005720 unsigned BeforeChildrenTokenIdx;
5721 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005722 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005723
5724 CXToken &getTok(unsigned Idx) {
5725 assert(Idx < NumTokens);
5726 return Tokens[Idx];
5727 }
5728 const CXToken &getTok(unsigned Idx) const {
5729 assert(Idx < NumTokens);
5730 return Tokens[Idx];
5731 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005732 bool MoreTokens() const { return TokIdx < NumTokens; }
5733 unsigned NextToken() const { return TokIdx; }
5734 void AdvanceToken() { ++TokIdx; }
5735 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005736 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005737 }
5738 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005739 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005740 }
5741 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005742 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005743 }
5744
5745 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005746 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005747 SourceRange);
5748
5749public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005750 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005751 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005752 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005753 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005754 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005755 AnnotateTokensVisitor, this,
5756 /*VisitPreprocessorLast=*/true,
5757 /*VisitIncludedEntities=*/false,
5758 RegionOfInterest,
5759 /*VisitDeclsOnly=*/false,
5760 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005761 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005762 HasContextSensitiveKeywords(false) { }
5763
5764 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5765 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5766 bool postVisitChildren(CXCursor cursor);
5767 void AnnotateTokens();
5768
5769 /// \brief Determine whether the annotator saw any cursors that have
5770 /// context-sensitive keywords.
5771 bool hasContextSensitiveKeywords() const {
5772 return HasContextSensitiveKeywords;
5773 }
5774
5775 ~AnnotateTokensWorker() {
5776 assert(PostChildrenInfos.empty());
5777 }
5778};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00005779}
Guy Benyei11169dd2012-12-18 14:30:41 +00005780
5781void AnnotateTokensWorker::AnnotateTokens() {
5782 // Walk the AST within the region of interest, annotating tokens
5783 // along the way.
5784 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005785}
Guy Benyei11169dd2012-12-18 14:30:41 +00005786
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005787static inline void updateCursorAnnotation(CXCursor &Cursor,
5788 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005789 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005790 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005791 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005792}
5793
5794/// \brief It annotates and advances tokens with a cursor until the comparison
5795//// between the cursor location and the source range is the same as
5796/// \arg compResult.
5797///
5798/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5799/// Pass RangeOverlap to annotate tokens inside a range.
5800void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5801 RangeComparisonResult compResult,
5802 SourceRange range) {
5803 while (MoreTokens()) {
5804 const unsigned I = NextToken();
5805 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005806 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5807 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005808
5809 SourceLocation TokLoc = GetTokenLoc(I);
5810 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005811 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005812 AdvanceToken();
5813 continue;
5814 }
5815 break;
5816 }
5817}
5818
5819/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005820/// \returns true if it advanced beyond all macro tokens, false otherwise.
5821bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005822 CXCursor updateC,
5823 RangeComparisonResult compResult,
5824 SourceRange range) {
5825 assert(MoreTokens());
5826 assert(isFunctionMacroToken(NextToken()) &&
5827 "Should be called only for macro arg tokens");
5828
5829 // This works differently than annotateAndAdvanceTokens; because expanded
5830 // macro arguments can have arbitrary translation-unit source order, we do not
5831 // advance the token index one by one until a token fails the range test.
5832 // We only advance once past all of the macro arg tokens if all of them
5833 // pass the range test. If one of them fails we keep the token index pointing
5834 // at the start of the macro arg tokens so that the failing token will be
5835 // annotated by a subsequent annotation try.
5836
5837 bool atLeastOneCompFail = false;
5838
5839 unsigned I = NextToken();
5840 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5841 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5842 if (TokLoc.isFileID())
5843 continue; // not macro arg token, it's parens or comma.
5844 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5845 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5846 Cursors[I] = updateC;
5847 } else
5848 atLeastOneCompFail = true;
5849 }
5850
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005851 if (atLeastOneCompFail)
5852 return false;
5853
5854 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5855 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005856}
5857
5858enum CXChildVisitResult
5859AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005860 SourceRange cursorRange = getRawCursorExtent(cursor);
5861 if (cursorRange.isInvalid())
5862 return CXChildVisit_Recurse;
5863
5864 if (!HasContextSensitiveKeywords) {
5865 // Objective-C properties can have context-sensitive keywords.
5866 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005867 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005868 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5869 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5870 }
5871 // Objective-C methods can have context-sensitive keywords.
5872 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5873 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005874 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005875 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5876 if (Method->getObjCDeclQualifier())
5877 HasContextSensitiveKeywords = true;
5878 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005879 for (const auto *P : Method->params()) {
5880 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005881 HasContextSensitiveKeywords = true;
5882 break;
5883 }
5884 }
5885 }
5886 }
5887 }
5888 // C++ methods can have context-sensitive keywords.
5889 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005890 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005891 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5892 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5893 HasContextSensitiveKeywords = true;
5894 }
5895 }
5896 // C++ classes can have context-sensitive keywords.
5897 else if (cursor.kind == CXCursor_StructDecl ||
5898 cursor.kind == CXCursor_ClassDecl ||
5899 cursor.kind == CXCursor_ClassTemplate ||
5900 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005901 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005902 if (D->hasAttr<FinalAttr>())
5903 HasContextSensitiveKeywords = true;
5904 }
5905 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005906
5907 // Don't override a property annotation with its getter/setter method.
5908 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5909 parent.kind == CXCursor_ObjCPropertyDecl)
5910 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005911
5912 if (clang_isPreprocessing(cursor.kind)) {
5913 // Items in the preprocessing record are kept separate from items in
5914 // declarations, so we keep a separate token index.
5915 unsigned SavedTokIdx = TokIdx;
5916 TokIdx = PreprocessingTokIdx;
5917
5918 // Skip tokens up until we catch up to the beginning of the preprocessing
5919 // entry.
5920 while (MoreTokens()) {
5921 const unsigned I = NextToken();
5922 SourceLocation TokLoc = GetTokenLoc(I);
5923 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5924 case RangeBefore:
5925 AdvanceToken();
5926 continue;
5927 case RangeAfter:
5928 case RangeOverlap:
5929 break;
5930 }
5931 break;
5932 }
5933
5934 // Look at all of the tokens within this range.
5935 while (MoreTokens()) {
5936 const unsigned I = NextToken();
5937 SourceLocation TokLoc = GetTokenLoc(I);
5938 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5939 case RangeBefore:
5940 llvm_unreachable("Infeasible");
5941 case RangeAfter:
5942 break;
5943 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005944 // For macro expansions, just note where the beginning of the macro
5945 // expansion occurs.
5946 if (cursor.kind == CXCursor_MacroExpansion) {
5947 if (TokLoc == cursorRange.getBegin())
5948 Cursors[I] = cursor;
5949 AdvanceToken();
5950 break;
5951 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005952 // We may have already annotated macro names inside macro definitions.
5953 if (Cursors[I].kind != CXCursor_MacroExpansion)
5954 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005955 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005956 continue;
5957 }
5958 break;
5959 }
5960
5961 // Save the preprocessing token index; restore the non-preprocessing
5962 // token index.
5963 PreprocessingTokIdx = TokIdx;
5964 TokIdx = SavedTokIdx;
5965 return CXChildVisit_Recurse;
5966 }
5967
5968 if (cursorRange.isInvalid())
5969 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005970
5971 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005972 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005973 const enum CXCursorKind K = clang_getCursorKind(parent);
5974 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005975 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5976 // Attributes are annotated out-of-order, skip tokens until we reach it.
5977 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005978 ? clang_getNullCursor() : parent;
5979
5980 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5981
5982 // Avoid having the cursor of an expression "overwrite" the annotation of the
5983 // variable declaration that it belongs to.
5984 // This can happen for C++ constructor expressions whose range generally
5985 // include the variable declaration, e.g.:
5986 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005987 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005988 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005989 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005990 const unsigned I = NextToken();
5991 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5992 E->getLocStart() == D->getLocation() &&
5993 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005994 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005995 AdvanceToken();
5996 }
5997 }
5998 }
5999
6000 // Before recursing into the children keep some state that we are going
6001 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
6002 // extra work after the child nodes are visited.
6003 // Note that we don't call VisitChildren here to avoid traversing statements
6004 // code-recursively which can blow the stack.
6005
6006 PostChildrenInfo Info;
6007 Info.Cursor = cursor;
6008 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006009 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006010 Info.BeforeChildrenTokenIdx = NextToken();
6011 PostChildrenInfos.push_back(Info);
6012
6013 return CXChildVisit_Recurse;
6014}
6015
6016bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
6017 if (PostChildrenInfos.empty())
6018 return false;
6019 const PostChildrenInfo &Info = PostChildrenInfos.back();
6020 if (!clang_equalCursors(Info.Cursor, cursor))
6021 return false;
6022
6023 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
6024 const unsigned AfterChildren = NextToken();
6025 SourceRange cursorRange = Info.CursorRange;
6026
6027 // Scan the tokens that are at the end of the cursor, but are not captured
6028 // but the child cursors.
6029 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
6030
6031 // Scan the tokens that are at the beginning of the cursor, but are not
6032 // capture by the child cursors.
6033 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
6034 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
6035 break;
6036
6037 Cursors[I] = cursor;
6038 }
6039
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006040 // Attributes are annotated out-of-order, rewind TokIdx to when we first
6041 // encountered the attribute cursor.
6042 if (clang_isAttribute(cursor.kind))
6043 TokIdx = Info.BeforeReachingCursorIdx;
6044
Guy Benyei11169dd2012-12-18 14:30:41 +00006045 PostChildrenInfos.pop_back();
6046 return false;
6047}
6048
6049static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
6050 CXCursor parent,
6051 CXClientData client_data) {
6052 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
6053}
6054
6055static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
6056 CXClientData client_data) {
6057 return static_cast<AnnotateTokensWorker*>(client_data)->
6058 postVisitChildren(cursor);
6059}
6060
6061namespace {
6062
6063/// \brief Uses the macro expansions in the preprocessing record to find
6064/// and mark tokens that are macro arguments. This info is used by the
6065/// AnnotateTokensWorker.
6066class MarkMacroArgTokensVisitor {
6067 SourceManager &SM;
6068 CXToken *Tokens;
6069 unsigned NumTokens;
6070 unsigned CurIdx;
6071
6072public:
6073 MarkMacroArgTokensVisitor(SourceManager &SM,
6074 CXToken *tokens, unsigned numTokens)
6075 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
6076
6077 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
6078 if (cursor.kind != CXCursor_MacroExpansion)
6079 return CXChildVisit_Continue;
6080
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006081 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00006082 if (macroRange.getBegin() == macroRange.getEnd())
6083 return CXChildVisit_Continue; // it's not a function macro.
6084
6085 for (; CurIdx < NumTokens; ++CurIdx) {
6086 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
6087 macroRange.getBegin()))
6088 break;
6089 }
6090
6091 if (CurIdx == NumTokens)
6092 return CXChildVisit_Break;
6093
6094 for (; CurIdx < NumTokens; ++CurIdx) {
6095 SourceLocation tokLoc = getTokenLoc(CurIdx);
6096 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
6097 break;
6098
6099 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
6100 }
6101
6102 if (CurIdx == NumTokens)
6103 return CXChildVisit_Break;
6104
6105 return CXChildVisit_Continue;
6106 }
6107
6108private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006109 CXToken &getTok(unsigned Idx) {
6110 assert(Idx < NumTokens);
6111 return Tokens[Idx];
6112 }
6113 const CXToken &getTok(unsigned Idx) const {
6114 assert(Idx < NumTokens);
6115 return Tokens[Idx];
6116 }
6117
Guy Benyei11169dd2012-12-18 14:30:41 +00006118 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006119 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006120 }
6121
6122 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
6123 // The third field is reserved and currently not used. Use it here
6124 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006125 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00006126 }
6127};
6128
6129} // end anonymous namespace
6130
6131static CXChildVisitResult
6132MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
6133 CXClientData client_data) {
6134 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
6135 parent);
6136}
6137
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006138/// \brief Used by \c annotatePreprocessorTokens.
6139/// \returns true if lexing was finished, false otherwise.
6140static bool lexNext(Lexer &Lex, Token &Tok,
6141 unsigned &NextIdx, unsigned NumTokens) {
6142 if (NextIdx >= NumTokens)
6143 return true;
6144
6145 ++NextIdx;
6146 Lex.LexFromRawLexer(Tok);
6147 if (Tok.is(tok::eof))
6148 return true;
6149
6150 return false;
6151}
6152
Guy Benyei11169dd2012-12-18 14:30:41 +00006153static void annotatePreprocessorTokens(CXTranslationUnit TU,
6154 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006155 CXCursor *Cursors,
6156 CXToken *Tokens,
6157 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006158 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006159
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006160 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00006161 SourceManager &SourceMgr = CXXUnit->getSourceManager();
6162 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006163 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00006164 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006165 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00006166
6167 if (BeginLocInfo.first != EndLocInfo.first)
6168 return;
6169
6170 StringRef Buffer;
6171 bool Invalid = false;
6172 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
6173 if (Buffer.empty() || Invalid)
6174 return;
6175
6176 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
6177 CXXUnit->getASTContext().getLangOpts(),
6178 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
6179 Buffer.end());
6180 Lex.SetCommentRetentionState(true);
6181
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006182 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006183 // Lex tokens in raw mode until we hit the end of the range, to avoid
6184 // entering #includes or expanding macros.
6185 while (true) {
6186 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006187 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6188 break;
6189 unsigned TokIdx = NextIdx-1;
6190 assert(Tok.getLocation() ==
6191 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006192
6193 reprocess:
6194 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006195 // We have found a preprocessing directive. Annotate the tokens
6196 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00006197 //
6198 // FIXME: Some simple tests here could identify macro definitions and
6199 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006200
6201 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006202 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6203 break;
6204
Craig Topper69186e72014-06-08 08:38:04 +00006205 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00006206 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006207 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6208 break;
6209
6210 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00006211 IdentifierInfo &II =
6212 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006213 SourceLocation MappedTokLoc =
6214 CXXUnit->mapLocationToPreamble(Tok.getLocation());
6215 MI = getMacroInfo(II, MappedTokLoc, TU);
6216 }
6217 }
6218
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006219 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00006220 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006221 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
6222 finished = true;
6223 break;
6224 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006225 // If we are in a macro definition, check if the token was ever a
6226 // macro name and annotate it if that's the case.
6227 if (MI) {
6228 SourceLocation SaveLoc = Tok.getLocation();
6229 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
Richard Smith66a81862015-05-04 02:25:31 +00006230 MacroDefinitionRecord *MacroDef =
6231 checkForMacroInMacroDefinition(MI, Tok, TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006232 Tok.setLocation(SaveLoc);
6233 if (MacroDef)
Richard Smith66a81862015-05-04 02:25:31 +00006234 Cursors[NextIdx - 1] =
6235 MakeMacroExpansionCursor(MacroDef, Tok.getLocation(), TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006236 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006237 } while (!Tok.isAtStartOfLine());
6238
6239 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
6240 assert(TokIdx <= LastIdx);
6241 SourceLocation EndLoc =
6242 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
6243 CXCursor Cursor =
6244 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
6245
6246 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006247 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006248
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006249 if (finished)
6250 break;
6251 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00006252 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006253 }
6254}
6255
6256// This gets run a separate thread to avoid stack blowout.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006257static void clang_annotateTokensImpl(CXTranslationUnit TU, ASTUnit *CXXUnit,
6258 CXToken *Tokens, unsigned NumTokens,
6259 CXCursor *Cursors) {
Dmitri Gribenko183436e2013-01-26 21:49:50 +00006260 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006261 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
6262 setThreadBackgroundPriority();
6263
6264 // Determine the region of interest, which contains all of the tokens.
6265 SourceRange RegionOfInterest;
6266 RegionOfInterest.setBegin(
6267 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
6268 RegionOfInterest.setEnd(
6269 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
6270 Tokens[NumTokens-1])));
6271
Guy Benyei11169dd2012-12-18 14:30:41 +00006272 // Relex the tokens within the source range to look for preprocessing
6273 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006274 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006275
6276 // If begin location points inside a macro argument, set it to the expansion
6277 // location so we can have the full context when annotating semantically.
6278 {
6279 SourceManager &SM = CXXUnit->getSourceManager();
6280 SourceLocation Loc =
6281 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
6282 if (Loc.isMacroID())
6283 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
6284 }
6285
Guy Benyei11169dd2012-12-18 14:30:41 +00006286 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
6287 // Search and mark tokens that are macro argument expansions.
6288 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
6289 Tokens, NumTokens);
6290 CursorVisitor MacroArgMarker(TU,
6291 MarkMacroArgTokensVisitorDelegate, &Visitor,
6292 /*VisitPreprocessorLast=*/true,
6293 /*VisitIncludedEntities=*/false,
6294 RegionOfInterest);
6295 MacroArgMarker.visitPreprocessedEntitiesInRegion();
6296 }
6297
6298 // Annotate all of the source locations in the region of interest that map to
6299 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006300 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00006301
6302 // FIXME: We use a ridiculous stack size here because the data-recursion
6303 // algorithm uses a large stack frame than the non-data recursive version,
6304 // and AnnotationTokensWorker currently transforms the data-recursion
6305 // algorithm back into a traditional recursion by explicitly calling
6306 // VisitChildren(). We will need to remove this explicit recursive call.
6307 W.AnnotateTokens();
6308
6309 // If we ran into any entities that involve context-sensitive keywords,
6310 // take another pass through the tokens to mark them as such.
6311 if (W.hasContextSensitiveKeywords()) {
6312 for (unsigned I = 0; I != NumTokens; ++I) {
6313 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
6314 continue;
6315
6316 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
6317 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006318 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006319 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
6320 if (Property->getPropertyAttributesAsWritten() != 0 &&
6321 llvm::StringSwitch<bool>(II->getName())
6322 .Case("readonly", true)
6323 .Case("assign", true)
6324 .Case("unsafe_unretained", true)
6325 .Case("readwrite", true)
6326 .Case("retain", true)
6327 .Case("copy", true)
6328 .Case("nonatomic", true)
6329 .Case("atomic", true)
6330 .Case("getter", true)
6331 .Case("setter", true)
6332 .Case("strong", true)
6333 .Case("weak", true)
6334 .Default(false))
6335 Tokens[I].int_data[0] = CXToken_Keyword;
6336 }
6337 continue;
6338 }
6339
6340 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6341 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6342 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6343 if (llvm::StringSwitch<bool>(II->getName())
6344 .Case("in", true)
6345 .Case("out", true)
6346 .Case("inout", true)
6347 .Case("oneway", true)
6348 .Case("bycopy", true)
6349 .Case("byref", true)
6350 .Default(false))
6351 Tokens[I].int_data[0] = CXToken_Keyword;
6352 continue;
6353 }
6354
6355 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6356 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6357 Tokens[I].int_data[0] = CXToken_Keyword;
6358 continue;
6359 }
6360 }
6361 }
6362}
6363
6364extern "C" {
6365
6366void clang_annotateTokens(CXTranslationUnit TU,
6367 CXToken *Tokens, unsigned NumTokens,
6368 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006369 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006370 LOG_BAD_TU(TU);
6371 return;
6372 }
6373 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006374 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006375 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006376 }
6377
6378 LOG_FUNC_SECTION {
6379 *Log << TU << ' ';
6380 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6381 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6382 *Log << clang_getRange(bloc, eloc);
6383 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006384
6385 // Any token we don't specifically annotate will have a NULL cursor.
6386 CXCursor C = clang_getNullCursor();
6387 for (unsigned I = 0; I != NumTokens; ++I)
6388 Cursors[I] = C;
6389
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006390 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006391 if (!CXXUnit)
6392 return;
6393
6394 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006395
6396 auto AnnotateTokensImpl = [=]() {
6397 clang_annotateTokensImpl(TU, CXXUnit, Tokens, NumTokens, Cursors);
6398 };
Guy Benyei11169dd2012-12-18 14:30:41 +00006399 llvm::CrashRecoveryContext CRC;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006400 if (!RunSafely(CRC, AnnotateTokensImpl, GetSafetyThreadStackSize() * 2)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006401 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6402 }
6403}
6404
6405} // end: extern "C"
6406
6407//===----------------------------------------------------------------------===//
6408// Operations for querying linkage of a cursor.
6409//===----------------------------------------------------------------------===//
6410
6411extern "C" {
6412CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6413 if (!clang_isDeclaration(cursor.kind))
6414 return CXLinkage_Invalid;
6415
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006416 const Decl *D = cxcursor::getCursorDecl(cursor);
6417 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006418 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006419 case NoLinkage:
6420 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006421 case InternalLinkage: return CXLinkage_Internal;
6422 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6423 case ExternalLinkage: return CXLinkage_External;
6424 };
6425
6426 return CXLinkage_Invalid;
6427}
6428} // end: extern "C"
6429
6430//===----------------------------------------------------------------------===//
6431// Operations for querying language of a cursor.
6432//===----------------------------------------------------------------------===//
6433
6434static CXLanguageKind getDeclLanguage(const Decl *D) {
6435 if (!D)
6436 return CXLanguage_C;
6437
6438 switch (D->getKind()) {
6439 default:
6440 break;
6441 case Decl::ImplicitParam:
6442 case Decl::ObjCAtDefsField:
6443 case Decl::ObjCCategory:
6444 case Decl::ObjCCategoryImpl:
6445 case Decl::ObjCCompatibleAlias:
6446 case Decl::ObjCImplementation:
6447 case Decl::ObjCInterface:
6448 case Decl::ObjCIvar:
6449 case Decl::ObjCMethod:
6450 case Decl::ObjCProperty:
6451 case Decl::ObjCPropertyImpl:
6452 case Decl::ObjCProtocol:
Douglas Gregor85f3f952015-07-07 03:57:15 +00006453 case Decl::ObjCTypeParam:
Guy Benyei11169dd2012-12-18 14:30:41 +00006454 return CXLanguage_ObjC;
6455 case Decl::CXXConstructor:
6456 case Decl::CXXConversion:
6457 case Decl::CXXDestructor:
6458 case Decl::CXXMethod:
6459 case Decl::CXXRecord:
6460 case Decl::ClassTemplate:
6461 case Decl::ClassTemplatePartialSpecialization:
6462 case Decl::ClassTemplateSpecialization:
6463 case Decl::Friend:
6464 case Decl::FriendTemplate:
6465 case Decl::FunctionTemplate:
6466 case Decl::LinkageSpec:
6467 case Decl::Namespace:
6468 case Decl::NamespaceAlias:
6469 case Decl::NonTypeTemplateParm:
6470 case Decl::StaticAssert:
6471 case Decl::TemplateTemplateParm:
6472 case Decl::TemplateTypeParm:
6473 case Decl::UnresolvedUsingTypename:
6474 case Decl::UnresolvedUsingValue:
6475 case Decl::Using:
6476 case Decl::UsingDirective:
6477 case Decl::UsingShadow:
6478 return CXLanguage_CPlusPlus;
6479 }
6480
6481 return CXLanguage_C;
6482}
6483
6484extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006485
6486static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6487 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
Manuel Klimek8e3a7ed2015-09-25 17:53:16 +00006488 return CXAvailability_NotAvailable;
Guy Benyei11169dd2012-12-18 14:30:41 +00006489
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006490 switch (D->getAvailability()) {
6491 case AR_Available:
6492 case AR_NotYetIntroduced:
6493 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006494 return getCursorAvailabilityForDecl(
6495 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006496 return CXAvailability_Available;
6497
6498 case AR_Deprecated:
6499 return CXAvailability_Deprecated;
6500
6501 case AR_Unavailable:
6502 return CXAvailability_NotAvailable;
6503 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006504
6505 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006506}
6507
Guy Benyei11169dd2012-12-18 14:30:41 +00006508enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6509 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006510 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6511 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006512
6513 return CXAvailability_Available;
6514}
6515
6516static CXVersion convertVersion(VersionTuple In) {
6517 CXVersion Out = { -1, -1, -1 };
6518 if (In.empty())
6519 return Out;
6520
6521 Out.Major = In.getMajor();
6522
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006523 Optional<unsigned> Minor = In.getMinor();
6524 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006525 Out.Minor = *Minor;
6526 else
6527 return Out;
6528
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006529 Optional<unsigned> Subminor = In.getSubminor();
6530 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006531 Out.Subminor = *Subminor;
6532
6533 return Out;
6534}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006535
6536static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6537 int *always_deprecated,
6538 CXString *deprecated_message,
6539 int *always_unavailable,
6540 CXString *unavailable_message,
6541 CXPlatformAvailability *availability,
6542 int availability_size) {
6543 bool HadAvailAttr = false;
6544 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006545 for (auto A : D->attrs()) {
6546 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006547 HadAvailAttr = true;
6548 if (always_deprecated)
6549 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006550 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006551 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006552 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006553 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006554 continue;
6555 }
6556
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006557 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006558 HadAvailAttr = true;
6559 if (always_unavailable)
6560 *always_unavailable = 1;
6561 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006562 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006563 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6564 }
6565 continue;
6566 }
6567
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006568 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006569 HadAvailAttr = true;
6570 if (N < availability_size) {
6571 availability[N].Platform
6572 = cxstring::createDup(Avail->getPlatform()->getName());
6573 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6574 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6575 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6576 availability[N].Unavailable = Avail->getUnavailable();
6577 availability[N].Message = cxstring::createDup(Avail->getMessage());
6578 }
6579 ++N;
6580 }
6581 }
6582
6583 if (!HadAvailAttr)
6584 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6585 return getCursorPlatformAvailabilityForDecl(
6586 cast<Decl>(EnumConst->getDeclContext()),
6587 always_deprecated,
6588 deprecated_message,
6589 always_unavailable,
6590 unavailable_message,
6591 availability,
6592 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006593
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006594 return N;
6595}
6596
Guy Benyei11169dd2012-12-18 14:30:41 +00006597int clang_getCursorPlatformAvailability(CXCursor cursor,
6598 int *always_deprecated,
6599 CXString *deprecated_message,
6600 int *always_unavailable,
6601 CXString *unavailable_message,
6602 CXPlatformAvailability *availability,
6603 int availability_size) {
6604 if (always_deprecated)
6605 *always_deprecated = 0;
6606 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006607 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006608 if (always_unavailable)
6609 *always_unavailable = 0;
6610 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006611 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006612
Guy Benyei11169dd2012-12-18 14:30:41 +00006613 if (!clang_isDeclaration(cursor.kind))
6614 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006615
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006616 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006617 if (!D)
6618 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006619
6620 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6621 deprecated_message,
6622 always_unavailable,
6623 unavailable_message,
6624 availability,
6625 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006626}
6627
6628void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6629 clang_disposeString(availability->Platform);
6630 clang_disposeString(availability->Message);
6631}
6632
6633CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6634 if (clang_isDeclaration(cursor.kind))
6635 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6636
6637 return CXLanguage_Invalid;
6638}
6639
6640 /// \brief If the given cursor is the "templated" declaration
6641 /// descibing a class or function template, return the class or
6642 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006643static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006644 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006645 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006646
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006647 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006648 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6649 return FunTmpl;
6650
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006651 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006652 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6653 return ClassTmpl;
6654
6655 return D;
6656}
6657
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006658
6659enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
6660 StorageClass sc = SC_None;
6661 const Decl *D = getCursorDecl(C);
6662 if (D) {
6663 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
6664 sc = FD->getStorageClass();
6665 } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
6666 sc = VD->getStorageClass();
6667 } else {
6668 return CX_SC_Invalid;
6669 }
6670 } else {
6671 return CX_SC_Invalid;
6672 }
6673 switch (sc) {
6674 case SC_None:
6675 return CX_SC_None;
6676 case SC_Extern:
6677 return CX_SC_Extern;
6678 case SC_Static:
6679 return CX_SC_Static;
6680 case SC_PrivateExtern:
6681 return CX_SC_PrivateExtern;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006682 case SC_Auto:
6683 return CX_SC_Auto;
6684 case SC_Register:
6685 return CX_SC_Register;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006686 }
Kaelyn Takataab61e702014-10-15 18:03:26 +00006687 llvm_unreachable("Unhandled storage class!");
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006688}
6689
Guy Benyei11169dd2012-12-18 14:30:41 +00006690CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6691 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006692 if (const Decl *D = getCursorDecl(cursor)) {
6693 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006694 if (!DC)
6695 return clang_getNullCursor();
6696
6697 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6698 getCursorTU(cursor));
6699 }
6700 }
6701
6702 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006703 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006704 return MakeCXCursor(D, getCursorTU(cursor));
6705 }
6706
6707 return clang_getNullCursor();
6708}
6709
6710CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6711 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006712 if (const Decl *D = getCursorDecl(cursor)) {
6713 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006714 if (!DC)
6715 return clang_getNullCursor();
6716
6717 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6718 getCursorTU(cursor));
6719 }
6720 }
6721
6722 // FIXME: Note that we can't easily compute the lexical context of a
6723 // statement or expression, so we return nothing.
6724 return clang_getNullCursor();
6725}
6726
6727CXFile clang_getIncludedFile(CXCursor cursor) {
6728 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006729 return nullptr;
6730
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006731 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006732 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006733}
6734
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006735unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6736 if (C.kind != CXCursor_ObjCPropertyDecl)
6737 return CXObjCPropertyAttr_noattr;
6738
6739 unsigned Result = CXObjCPropertyAttr_noattr;
6740 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6741 ObjCPropertyDecl::PropertyAttributeKind Attr =
6742 PD->getPropertyAttributesAsWritten();
6743
6744#define SET_CXOBJCPROP_ATTR(A) \
6745 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6746 Result |= CXObjCPropertyAttr_##A
6747 SET_CXOBJCPROP_ATTR(readonly);
6748 SET_CXOBJCPROP_ATTR(getter);
6749 SET_CXOBJCPROP_ATTR(assign);
6750 SET_CXOBJCPROP_ATTR(readwrite);
6751 SET_CXOBJCPROP_ATTR(retain);
6752 SET_CXOBJCPROP_ATTR(copy);
6753 SET_CXOBJCPROP_ATTR(nonatomic);
6754 SET_CXOBJCPROP_ATTR(setter);
6755 SET_CXOBJCPROP_ATTR(atomic);
6756 SET_CXOBJCPROP_ATTR(weak);
6757 SET_CXOBJCPROP_ATTR(strong);
6758 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6759#undef SET_CXOBJCPROP_ATTR
6760
6761 return Result;
6762}
6763
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006764unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6765 if (!clang_isDeclaration(C.kind))
6766 return CXObjCDeclQualifier_None;
6767
6768 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6769 const Decl *D = getCursorDecl(C);
6770 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6771 QT = MD->getObjCDeclQualifier();
6772 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6773 QT = PD->getObjCDeclQualifier();
6774 if (QT == Decl::OBJC_TQ_None)
6775 return CXObjCDeclQualifier_None;
6776
6777 unsigned Result = CXObjCDeclQualifier_None;
6778 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6779 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6780 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6781 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6782 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6783 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6784
6785 return Result;
6786}
6787
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006788unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6789 if (!clang_isDeclaration(C.kind))
6790 return 0;
6791
6792 const Decl *D = getCursorDecl(C);
6793 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6794 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6795 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6796 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6797
6798 return 0;
6799}
6800
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006801unsigned clang_Cursor_isVariadic(CXCursor C) {
6802 if (!clang_isDeclaration(C.kind))
6803 return 0;
6804
6805 const Decl *D = getCursorDecl(C);
6806 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6807 return FD->isVariadic();
6808 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6809 return MD->isVariadic();
6810
6811 return 0;
6812}
6813
Guy Benyei11169dd2012-12-18 14:30:41 +00006814CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6815 if (!clang_isDeclaration(C.kind))
6816 return clang_getNullRange();
6817
6818 const Decl *D = getCursorDecl(C);
6819 ASTContext &Context = getCursorContext(C);
6820 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6821 if (!RC)
6822 return clang_getNullRange();
6823
6824 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6825}
6826
6827CXString clang_Cursor_getRawCommentText(CXCursor C) {
6828 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006829 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006830
6831 const Decl *D = getCursorDecl(C);
6832 ASTContext &Context = getCursorContext(C);
6833 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6834 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6835 StringRef();
6836
6837 // Don't duplicate the string because RawText points directly into source
6838 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006839 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006840}
6841
6842CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6843 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006844 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006845
6846 const Decl *D = getCursorDecl(C);
6847 const ASTContext &Context = getCursorContext(C);
6848 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6849
6850 if (RC) {
6851 StringRef BriefText = RC->getBriefText(Context);
6852
6853 // Don't duplicate the string because RawComment ensures that this memory
6854 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006855 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006856 }
6857
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006858 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006859}
6860
Guy Benyei11169dd2012-12-18 14:30:41 +00006861CXModule clang_Cursor_getModule(CXCursor C) {
6862 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006863 if (const ImportDecl *ImportD =
6864 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006865 return ImportD->getImportedModule();
6866 }
6867
Craig Topper69186e72014-06-08 08:38:04 +00006868 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006869}
6870
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006871CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6872 if (isNotUsableTU(TU)) {
6873 LOG_BAD_TU(TU);
6874 return nullptr;
6875 }
6876 if (!File)
6877 return nullptr;
6878 FileEntry *FE = static_cast<FileEntry *>(File);
6879
6880 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6881 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6882 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6883
Richard Smithfeb54b62014-10-23 02:01:19 +00006884 return Header.getModule();
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006885}
6886
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006887CXFile clang_Module_getASTFile(CXModule CXMod) {
6888 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006889 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006890 Module *Mod = static_cast<Module*>(CXMod);
6891 return const_cast<FileEntry *>(Mod->getASTFile());
6892}
6893
Guy Benyei11169dd2012-12-18 14:30:41 +00006894CXModule clang_Module_getParent(CXModule CXMod) {
6895 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006896 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006897 Module *Mod = static_cast<Module*>(CXMod);
6898 return Mod->Parent;
6899}
6900
6901CXString clang_Module_getName(CXModule CXMod) {
6902 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006903 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006904 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006905 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006906}
6907
6908CXString clang_Module_getFullName(CXModule CXMod) {
6909 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006910 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006911 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006912 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006913}
6914
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006915int clang_Module_isSystem(CXModule CXMod) {
6916 if (!CXMod)
6917 return 0;
6918 Module *Mod = static_cast<Module*>(CXMod);
6919 return Mod->IsSystem;
6920}
6921
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006922unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6923 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006924 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006925 LOG_BAD_TU(TU);
6926 return 0;
6927 }
6928 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006929 return 0;
6930 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006931 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6932 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6933 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006934}
6935
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006936CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6937 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006938 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006939 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006940 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006941 }
6942 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006943 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006944 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006945 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006946
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006947 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6948 if (Index < TopHeaders.size())
6949 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006950
Craig Topper69186e72014-06-08 08:38:04 +00006951 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006952}
6953
6954} // end: extern "C"
6955
6956//===----------------------------------------------------------------------===//
6957// C++ AST instrospection.
6958//===----------------------------------------------------------------------===//
6959
6960extern "C" {
Saleem Abdulrasool6ea75db2015-10-27 15:50:22 +00006961unsigned clang_CXXField_isMutable(CXCursor C) {
6962 if (!clang_isDeclaration(C.kind))
6963 return 0;
6964
6965 if (const auto D = cxcursor::getCursorDecl(C))
6966 if (const auto FD = dyn_cast_or_null<FieldDecl>(D))
6967 return FD->isMutable() ? 1 : 0;
6968 return 0;
6969}
6970
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006971unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6972 if (!clang_isDeclaration(C.kind))
6973 return 0;
6974
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006975 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006976 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006977 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006978 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6979}
6980
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006981unsigned clang_CXXMethod_isConst(CXCursor C) {
6982 if (!clang_isDeclaration(C.kind))
6983 return 0;
6984
6985 const Decl *D = cxcursor::getCursorDecl(C);
6986 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006987 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006988 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6989}
6990
Guy Benyei11169dd2012-12-18 14:30:41 +00006991unsigned clang_CXXMethod_isStatic(CXCursor C) {
6992 if (!clang_isDeclaration(C.kind))
6993 return 0;
6994
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006995 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006996 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006997 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006998 return (Method && Method->isStatic()) ? 1 : 0;
6999}
7000
7001unsigned clang_CXXMethod_isVirtual(CXCursor C) {
7002 if (!clang_isDeclaration(C.kind))
7003 return 0;
7004
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007005 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007006 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007007 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007008 return (Method && Method->isVirtual()) ? 1 : 0;
7009}
7010} // end: extern "C"
7011
7012//===----------------------------------------------------------------------===//
7013// Attribute introspection.
7014//===----------------------------------------------------------------------===//
7015
7016extern "C" {
7017CXType clang_getIBOutletCollectionType(CXCursor C) {
7018 if (C.kind != CXCursor_IBOutletCollectionAttr)
7019 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
7020
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00007021 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00007022 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
7023
7024 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
7025}
7026} // end: extern "C"
7027
7028//===----------------------------------------------------------------------===//
7029// Inspecting memory usage.
7030//===----------------------------------------------------------------------===//
7031
7032typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
7033
7034static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
7035 enum CXTUResourceUsageKind k,
7036 unsigned long amount) {
7037 CXTUResourceUsageEntry entry = { k, amount };
7038 entries.push_back(entry);
7039}
7040
7041extern "C" {
7042
7043const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
7044 const char *str = "";
7045 switch (kind) {
7046 case CXTUResourceUsage_AST:
7047 str = "ASTContext: expressions, declarations, and types";
7048 break;
7049 case CXTUResourceUsage_Identifiers:
7050 str = "ASTContext: identifiers";
7051 break;
7052 case CXTUResourceUsage_Selectors:
7053 str = "ASTContext: selectors";
7054 break;
7055 case CXTUResourceUsage_GlobalCompletionResults:
7056 str = "Code completion: cached global results";
7057 break;
7058 case CXTUResourceUsage_SourceManagerContentCache:
7059 str = "SourceManager: content cache allocator";
7060 break;
7061 case CXTUResourceUsage_AST_SideTables:
7062 str = "ASTContext: side tables";
7063 break;
7064 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
7065 str = "SourceManager: malloc'ed memory buffers";
7066 break;
7067 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
7068 str = "SourceManager: mmap'ed memory buffers";
7069 break;
7070 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
7071 str = "ExternalASTSource: malloc'ed memory buffers";
7072 break;
7073 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
7074 str = "ExternalASTSource: mmap'ed memory buffers";
7075 break;
7076 case CXTUResourceUsage_Preprocessor:
7077 str = "Preprocessor: malloc'ed memory";
7078 break;
7079 case CXTUResourceUsage_PreprocessingRecord:
7080 str = "Preprocessor: PreprocessingRecord";
7081 break;
7082 case CXTUResourceUsage_SourceManager_DataStructures:
7083 str = "SourceManager: data structures and tables";
7084 break;
7085 case CXTUResourceUsage_Preprocessor_HeaderSearch:
7086 str = "Preprocessor: header search tables";
7087 break;
7088 }
7089 return str;
7090}
7091
7092CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007093 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007094 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00007095 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00007096 return usage;
7097 }
7098
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007099 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00007100 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00007101 ASTContext &astContext = astUnit->getASTContext();
7102
7103 // How much memory is used by AST nodes and types?
7104 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
7105 (unsigned long) astContext.getASTAllocatedMemory());
7106
7107 // How much memory is used by identifiers?
7108 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
7109 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
7110
7111 // How much memory is used for selectors?
7112 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
7113 (unsigned long) astContext.Selectors.getTotalMemory());
7114
7115 // How much memory is used by ASTContext's side tables?
7116 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
7117 (unsigned long) astContext.getSideTableAllocatedMemory());
7118
7119 // How much memory is used for caching global code completion results?
7120 unsigned long completionBytes = 0;
7121 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00007122 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007123 completionBytes = completionAllocator->getTotalMemory();
7124 }
7125 createCXTUResourceUsageEntry(*entries,
7126 CXTUResourceUsage_GlobalCompletionResults,
7127 completionBytes);
7128
7129 // How much memory is being used by SourceManager's content cache?
7130 createCXTUResourceUsageEntry(*entries,
7131 CXTUResourceUsage_SourceManagerContentCache,
7132 (unsigned long) astContext.getSourceManager().getContentCacheSize());
7133
7134 // How much memory is being used by the MemoryBuffer's in SourceManager?
7135 const SourceManager::MemoryBufferSizes &srcBufs =
7136 astUnit->getSourceManager().getMemoryBufferSizes();
7137
7138 createCXTUResourceUsageEntry(*entries,
7139 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
7140 (unsigned long) srcBufs.malloc_bytes);
7141 createCXTUResourceUsageEntry(*entries,
7142 CXTUResourceUsage_SourceManager_Membuffer_MMap,
7143 (unsigned long) srcBufs.mmap_bytes);
7144 createCXTUResourceUsageEntry(*entries,
7145 CXTUResourceUsage_SourceManager_DataStructures,
7146 (unsigned long) astContext.getSourceManager()
7147 .getDataStructureSizes());
7148
7149 // How much memory is being used by the ExternalASTSource?
7150 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
7151 const ExternalASTSource::MemoryBufferSizes &sizes =
7152 esrc->getMemoryBufferSizes();
7153
7154 createCXTUResourceUsageEntry(*entries,
7155 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
7156 (unsigned long) sizes.malloc_bytes);
7157 createCXTUResourceUsageEntry(*entries,
7158 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
7159 (unsigned long) sizes.mmap_bytes);
7160 }
7161
7162 // How much memory is being used by the Preprocessor?
7163 Preprocessor &pp = astUnit->getPreprocessor();
7164 createCXTUResourceUsageEntry(*entries,
7165 CXTUResourceUsage_Preprocessor,
7166 pp.getTotalMemory());
7167
7168 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
7169 createCXTUResourceUsageEntry(*entries,
7170 CXTUResourceUsage_PreprocessingRecord,
7171 pRec->getTotalMemory());
7172 }
7173
7174 createCXTUResourceUsageEntry(*entries,
7175 CXTUResourceUsage_Preprocessor_HeaderSearch,
7176 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00007177
Guy Benyei11169dd2012-12-18 14:30:41 +00007178 CXTUResourceUsage usage = { (void*) entries.get(),
7179 (unsigned) entries->size(),
Alexander Kornienko6ee521c2015-01-23 15:36:10 +00007180 !entries->empty() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00007181 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00007182 return usage;
7183}
7184
7185void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
7186 if (usage.data)
7187 delete (MemUsageEntries*) usage.data;
7188}
7189
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007190CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
7191 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007192 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00007193 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007194
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007195 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007196 LOG_BAD_TU(TU);
7197 return skipped;
7198 }
7199
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007200 if (!file)
7201 return skipped;
7202
7203 ASTUnit *astUnit = cxtu::getASTUnit(TU);
7204 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
7205 if (!ppRec)
7206 return skipped;
7207
7208 ASTContext &Ctx = astUnit->getASTContext();
7209 SourceManager &sm = Ctx.getSourceManager();
7210 FileEntry *fileEntry = static_cast<FileEntry *>(file);
7211 FileID wantedFileID = sm.translateFile(fileEntry);
7212
7213 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
7214 std::vector<SourceRange> wantedRanges;
7215 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
7216 i != ei; ++i) {
7217 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
7218 wantedRanges.push_back(*i);
7219 }
7220
7221 skipped->count = wantedRanges.size();
7222 skipped->ranges = new CXSourceRange[skipped->count];
7223 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
7224 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
7225
7226 return skipped;
7227}
7228
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007229void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
7230 if (ranges) {
7231 delete[] ranges->ranges;
7232 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007233 }
7234}
7235
Guy Benyei11169dd2012-12-18 14:30:41 +00007236} // end extern "C"
7237
7238void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
7239 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
7240 for (unsigned I = 0; I != Usage.numEntries; ++I)
7241 fprintf(stderr, " %s: %lu\n",
7242 clang_getTUResourceUsageName(Usage.entries[I].kind),
7243 Usage.entries[I].amount);
7244
7245 clang_disposeCXTUResourceUsage(Usage);
7246}
7247
7248//===----------------------------------------------------------------------===//
7249// Misc. utility functions.
7250//===----------------------------------------------------------------------===//
7251
7252/// Default to using an 8 MB stack size on "safety" threads.
7253static unsigned SafetyStackThreadSize = 8 << 20;
7254
7255namespace clang {
7256
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007257bool RunSafely(llvm::CrashRecoveryContext &CRC, llvm::function_ref<void()> Fn,
Guy Benyei11169dd2012-12-18 14:30:41 +00007258 unsigned Size) {
7259 if (!Size)
7260 Size = GetSafetyThreadStackSize();
7261 if (Size)
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007262 return CRC.RunSafelyOnThread(Fn, Size);
7263 return CRC.RunSafely(Fn);
Guy Benyei11169dd2012-12-18 14:30:41 +00007264}
7265
7266unsigned GetSafetyThreadStackSize() {
7267 return SafetyStackThreadSize;
7268}
7269
7270void SetSafetyThreadStackSize(unsigned Value) {
7271 SafetyStackThreadSize = Value;
7272}
7273
Alexander Kornienkoab9db512015-06-22 23:07:51 +00007274}
Guy Benyei11169dd2012-12-18 14:30:41 +00007275
7276void clang::setThreadBackgroundPriority() {
7277 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
7278 return;
7279
Alp Toker1a86ad22014-07-06 06:24:00 +00007280#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00007281 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
7282#endif
7283}
7284
7285void cxindex::printDiagsToStderr(ASTUnit *Unit) {
7286 if (!Unit)
7287 return;
7288
7289 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
7290 DEnd = Unit->stored_diag_end();
7291 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00007292 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00007293 CXString Msg = clang_formatDiagnostic(&Diag,
7294 clang_defaultDiagnosticDisplayOptions());
7295 fprintf(stderr, "%s\n", clang_getCString(Msg));
7296 clang_disposeString(Msg);
7297 }
7298#ifdef LLVM_ON_WIN32
7299 // On Windows, force a flush, since there may be multiple copies of
7300 // stderr and stdout in the file system, all with different buffers
7301 // but writing to the same device.
7302 fflush(stderr);
7303#endif
7304}
7305
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007306MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
7307 SourceLocation MacroDefLoc,
7308 CXTranslationUnit TU){
7309 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007310 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007311 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007312 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007313
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007314 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007315 Preprocessor &PP = Unit->getPreprocessor();
Richard Smith20e883e2015-04-29 23:20:19 +00007316 MacroDirective *MD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007317 if (MD) {
7318 for (MacroDirective::DefInfo
7319 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
7320 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
7321 return Def.getMacroInfo();
7322 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007323 }
7324
Craig Topper69186e72014-06-08 08:38:04 +00007325 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007326}
7327
Richard Smith66a81862015-05-04 02:25:31 +00007328const MacroInfo *cxindex::getMacroInfo(const MacroDefinitionRecord *MacroDef,
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007329 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007330 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007331 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007332 const IdentifierInfo *II = MacroDef->getName();
7333 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00007334 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007335
7336 return getMacroInfo(*II, MacroDef->getLocation(), TU);
7337}
7338
Richard Smith66a81862015-05-04 02:25:31 +00007339MacroDefinitionRecord *
7340cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, const Token &Tok,
7341 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007342 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007343 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007344 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00007345 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007346
7347 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007348 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007349 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
7350 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007351 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007352
7353 // Check that the token is inside the definition and not its argument list.
7354 SourceManager &SM = Unit->getSourceManager();
7355 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00007356 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007357 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00007358 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007359
7360 Preprocessor &PP = Unit->getPreprocessor();
7361 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
7362 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00007363 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007364
Alp Toker2d57cea2014-05-17 04:53:25 +00007365 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007366 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007367 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007368
7369 // Check that the identifier is not one of the macro arguments.
7370 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00007371 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007372
Richard Smith20e883e2015-04-29 23:20:19 +00007373 MacroDirective *InnerMD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007374 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00007375 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007376
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007377 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007378}
7379
Richard Smith66a81862015-05-04 02:25:31 +00007380MacroDefinitionRecord *
7381cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, SourceLocation Loc,
7382 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007383 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007384 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007385
7386 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007387 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007388 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007389 Preprocessor &PP = Unit->getPreprocessor();
7390 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00007391 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007392 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7393 Token Tok;
7394 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00007395 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007396
7397 return checkForMacroInMacroDefinition(MI, Tok, TU);
7398}
7399
Guy Benyei11169dd2012-12-18 14:30:41 +00007400extern "C" {
7401
7402CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007403 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00007404}
7405
7406} // end: extern "C"
7407
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007408Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7409 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007410 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007411 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007412 if (Unit->isMainFileAST())
7413 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007414 return *this;
7415 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007416 } else {
7417 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007418 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007419 return *this;
7420}
7421
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007422Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7423 *this << FE->getName();
7424 return *this;
7425}
7426
7427Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7428 CXString cursorName = clang_getCursorDisplayName(cursor);
7429 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7430 clang_disposeString(cursorName);
7431 return *this;
7432}
7433
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007434Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7435 CXFile File;
7436 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007437 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007438 CXString FileName = clang_getFileName(File);
7439 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7440 clang_disposeString(FileName);
7441 return *this;
7442}
7443
7444Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7445 CXSourceLocation BLoc = clang_getRangeStart(range);
7446 CXSourceLocation ELoc = clang_getRangeEnd(range);
7447
7448 CXFile BFile;
7449 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007450 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007451
7452 CXFile EFile;
7453 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007454 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007455
7456 CXString BFileName = clang_getFileName(BFile);
7457 if (BFile == EFile) {
7458 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7459 BLine, BColumn, ELine, EColumn);
7460 } else {
7461 CXString EFileName = clang_getFileName(EFile);
7462 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7463 BLine, BColumn)
7464 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7465 ELine, EColumn);
7466 clang_disposeString(EFileName);
7467 }
7468 clang_disposeString(BFileName);
7469 return *this;
7470}
7471
7472Logger &cxindex::Logger::operator<<(CXString Str) {
7473 *this << clang_getCString(Str);
7474 return *this;
7475}
7476
7477Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7478 LogOS << Fmt;
7479 return *this;
7480}
7481
Chandler Carruth37ad2582014-06-27 15:14:39 +00007482static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7483
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007484cxindex::Logger::~Logger() {
Chandler Carruth37ad2582014-06-27 15:14:39 +00007485 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007486
7487 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7488
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007489 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007490 OS << "[libclang:" << Name << ':';
7491
Alp Toker1a86ad22014-07-06 06:24:00 +00007492#ifdef USE_DARWIN_THREADS
7493 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007494 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7495 OS << tid << ':';
7496#endif
7497
7498 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7499 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
Yaron Keren09fb7c62015-03-10 07:33:23 +00007500 OS << Msg << '\n';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007501
7502 if (Trace) {
Zachary Turner1fe2a8d2015-03-05 19:15:09 +00007503 llvm::sys::PrintStackTrace(OS);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007504 OS << "--------------------------------------------------\n";
7505 }
7506}