blob: bdefa9b71b0702beebd695a32f6bac9dc30bfa46 [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"
56#include "llvm/Support/Threading.h"
57#include "llvm/Support/Timer.h"
58#include "llvm/Support/raw_ostream.h"
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000059
Alp Toker1a86ad22014-07-06 06:24:00 +000060#if LLVM_ENABLE_THREADS != 0 && defined(__APPLE__)
61#define USE_DARWIN_THREADS
62#endif
63
64#ifdef USE_DARWIN_THREADS
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000065#include <pthread.h>
66#endif
Guy Benyei11169dd2012-12-18 14:30:41 +000067
68using namespace clang;
69using namespace clang::cxcursor;
Guy Benyei11169dd2012-12-18 14:30:41 +000070using namespace clang::cxtu;
71using namespace clang::cxindex;
72
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000073CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) {
74 if (!AU)
Craig Topper69186e72014-06-08 08:38:04 +000075 return nullptr;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000076 assert(CIdx);
Guy Benyei11169dd2012-12-18 14:30:41 +000077 CXTranslationUnit D = new CXTranslationUnitImpl();
78 D->CIdx = CIdx;
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000079 D->TheASTUnit = AU;
Dmitri Gribenko74895212013-02-03 13:52:47 +000080 D->StringPool = new cxstring::CXStringPool();
Craig Topper69186e72014-06-08 08:38:04 +000081 D->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000082 D->OverridenCursorsPool = createOverridenCXCursorsPool();
Craig Topper69186e72014-06-08 08:38:04 +000083 D->CommentToXML = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000084 return D;
85}
86
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000087bool cxtu::isASTReadError(ASTUnit *AU) {
88 for (ASTUnit::stored_diag_iterator D = AU->stored_diag_begin(),
89 DEnd = AU->stored_diag_end();
90 D != DEnd; ++D) {
91 if (D->getLevel() >= DiagnosticsEngine::Error &&
92 DiagnosticIDs::getCategoryNumberForDiag(D->getID()) ==
93 diag::DiagCat_AST_Deserialization_Issue)
94 return true;
95 }
96 return false;
97}
98
Guy Benyei11169dd2012-12-18 14:30:41 +000099cxtu::CXTUOwner::~CXTUOwner() {
100 if (TU)
101 clang_disposeTranslationUnit(TU);
102}
103
104/// \brief Compare two source ranges to determine their relative position in
105/// the translation unit.
106static RangeComparisonResult RangeCompare(SourceManager &SM,
107 SourceRange R1,
108 SourceRange R2) {
109 assert(R1.isValid() && "First range is invalid?");
110 assert(R2.isValid() && "Second range is invalid?");
111 if (R1.getEnd() != R2.getBegin() &&
112 SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
113 return RangeBefore;
114 if (R2.getEnd() != R1.getBegin() &&
115 SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
116 return RangeAfter;
117 return RangeOverlap;
118}
119
120/// \brief Determine if a source location falls within, before, or after a
121/// a given source range.
122static RangeComparisonResult LocationCompare(SourceManager &SM,
123 SourceLocation L, SourceRange R) {
124 assert(R.isValid() && "First range is invalid?");
125 assert(L.isValid() && "Second range is invalid?");
126 if (L == R.getBegin() || L == R.getEnd())
127 return RangeOverlap;
128 if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
129 return RangeBefore;
130 if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
131 return RangeAfter;
132 return RangeOverlap;
133}
134
135/// \brief Translate a Clang source range into a CIndex source range.
136///
137/// Clang internally represents ranges where the end location points to the
138/// start of the token at the end. However, for external clients it is more
139/// useful to have a CXSourceRange be a proper half-open interval. This routine
140/// does the appropriate translation.
141CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
142 const LangOptions &LangOpts,
143 const CharSourceRange &R) {
144 // We want the last character in this location, so we will adjust the
145 // location accordingly.
146 SourceLocation EndLoc = R.getEnd();
147 if (EndLoc.isValid() && EndLoc.isMacroID() && !SM.isMacroArgExpansion(EndLoc))
148 EndLoc = SM.getExpansionRange(EndLoc).second;
149 if (R.isTokenRange() && !EndLoc.isInvalid()) {
150 unsigned Length = Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc),
151 SM, LangOpts);
152 EndLoc = EndLoc.getLocWithOffset(Length);
153 }
154
Bill Wendlingeade3622013-01-23 08:25:41 +0000155 CXSourceRange Result = {
Dmitri Gribenkof9304482013-01-23 15:56:07 +0000156 { &SM, &LangOpts },
Bill Wendlingeade3622013-01-23 08:25:41 +0000157 R.getBegin().getRawEncoding(),
158 EndLoc.getRawEncoding()
159 };
Guy Benyei11169dd2012-12-18 14:30:41 +0000160 return Result;
161}
162
163//===----------------------------------------------------------------------===//
164// Cursor visitor.
165//===----------------------------------------------------------------------===//
166
167static SourceRange getRawCursorExtent(CXCursor C);
168static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
169
170
171RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
172 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
173}
174
175/// \brief Visit the given cursor and, if requested by the visitor,
176/// its children.
177///
178/// \param Cursor the cursor to visit.
179///
180/// \param CheckedRegionOfInterest if true, then the caller already checked
181/// that this cursor is within the region of interest.
182///
183/// \returns true if the visitation should be aborted, false if it
184/// should continue.
185bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
186 if (clang_isInvalid(Cursor.kind))
187 return false;
188
189 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000190 const Decl *D = getCursorDecl(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000191 if (!D) {
192 assert(0 && "Invalid declaration cursor");
193 return true; // abort.
194 }
195
196 // Ignore implicit declarations, unless it's an objc method because
197 // currently we should report implicit methods for properties when indexing.
198 if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
199 return false;
200 }
201
202 // If we have a range of interest, and this cursor doesn't intersect with it,
203 // we're done.
204 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
205 SourceRange Range = getRawCursorExtent(Cursor);
206 if (Range.isInvalid() || CompareRegionOfInterest(Range))
207 return false;
208 }
209
210 switch (Visitor(Cursor, Parent, ClientData)) {
211 case CXChildVisit_Break:
212 return true;
213
214 case CXChildVisit_Continue:
215 return false;
216
217 case CXChildVisit_Recurse: {
218 bool ret = VisitChildren(Cursor);
219 if (PostChildrenVisitor)
220 if (PostChildrenVisitor(Cursor, ClientData))
221 return true;
222 return ret;
223 }
224 }
225
226 llvm_unreachable("Invalid CXChildVisitResult!");
227}
228
229static bool visitPreprocessedEntitiesInRange(SourceRange R,
230 PreprocessingRecord &PPRec,
231 CursorVisitor &Visitor) {
232 SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
233 FileID FID;
234
235 if (!Visitor.shouldVisitIncludedEntities()) {
236 // If the begin/end of the range lie in the same FileID, do the optimization
237 // where we skip preprocessed entities that do not come from the same FileID.
238 FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
239 if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
240 FID = FileID();
241 }
242
Benjamin Kramerb4ef6682015-02-06 17:25:10 +0000243 const auto &Entities = PPRec.getPreprocessedEntitiesInRange(R);
244 return Visitor.visitPreprocessedEntities(Entities.begin(), Entities.end(),
Guy Benyei11169dd2012-12-18 14:30:41 +0000245 PPRec, FID);
246}
247
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000248bool CursorVisitor::visitFileRegion() {
Guy Benyei11169dd2012-12-18 14:30:41 +0000249 if (RegionOfInterest.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000250 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000251
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000252 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000253 SourceManager &SM = Unit->getSourceManager();
254
255 std::pair<FileID, unsigned>
256 Begin = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getBegin())),
257 End = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getEnd()));
258
259 if (End.first != Begin.first) {
260 // If the end does not reside in the same file, try to recover by
261 // picking the end of the file of begin location.
262 End.first = Begin.first;
263 End.second = SM.getFileIDSize(Begin.first);
264 }
265
266 assert(Begin.first == End.first);
267 if (Begin.second > End.second)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000268 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000269
270 FileID File = Begin.first;
271 unsigned Offset = Begin.second;
272 unsigned Length = End.second - Begin.second;
273
274 if (!VisitDeclsOnly && !VisitPreprocessorLast)
275 if (visitPreprocessedEntitiesInRegion())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000276 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000277
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000278 if (visitDeclsFromFileRegion(File, Offset, Length))
279 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000280
281 if (!VisitDeclsOnly && VisitPreprocessorLast)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000282 return visitPreprocessedEntitiesInRegion();
283
284 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000285}
286
287static bool isInLexicalContext(Decl *D, DeclContext *DC) {
288 if (!DC)
289 return false;
290
291 for (DeclContext *DeclDC = D->getLexicalDeclContext();
292 DeclDC; DeclDC = DeclDC->getLexicalParent()) {
293 if (DeclDC == DC)
294 return true;
295 }
296 return false;
297}
298
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000299bool CursorVisitor::visitDeclsFromFileRegion(FileID File,
Guy Benyei11169dd2012-12-18 14:30:41 +0000300 unsigned Offset, unsigned Length) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000301 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000302 SourceManager &SM = Unit->getSourceManager();
303 SourceRange Range = RegionOfInterest;
304
305 SmallVector<Decl *, 16> Decls;
306 Unit->findFileRegionDecls(File, Offset, Length, Decls);
307
308 // If we didn't find any file level decls for the file, try looking at the
309 // file that it was included from.
310 while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
311 bool Invalid = false;
312 const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
313 if (Invalid)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000314 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000315
316 SourceLocation Outer;
317 if (SLEntry.isFile())
318 Outer = SLEntry.getFile().getIncludeLoc();
319 else
320 Outer = SLEntry.getExpansion().getExpansionLocStart();
321 if (Outer.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000322 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000323
Benjamin Kramer867ea1d2014-03-02 13:01:17 +0000324 std::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
Guy Benyei11169dd2012-12-18 14:30:41 +0000325 Length = 0;
326 Unit->findFileRegionDecls(File, Offset, Length, Decls);
327 }
328
329 assert(!Decls.empty());
330
331 bool VisitedAtLeastOnce = false;
Craig Topper69186e72014-06-08 08:38:04 +0000332 DeclContext *CurDC = nullptr;
Craig Topper2341c0d2013-07-04 03:08:24 +0000333 SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
334 for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000335 Decl *D = *DIt;
336 if (D->getSourceRange().isInvalid())
337 continue;
338
339 if (isInLexicalContext(D, CurDC))
340 continue;
341
342 CurDC = dyn_cast<DeclContext>(D);
343
344 if (TagDecl *TD = dyn_cast<TagDecl>(D))
345 if (!TD->isFreeStanding())
346 continue;
347
348 RangeComparisonResult CompRes = RangeCompare(SM, D->getSourceRange(),Range);
349 if (CompRes == RangeBefore)
350 continue;
351 if (CompRes == RangeAfter)
352 break;
353
354 assert(CompRes == RangeOverlap);
355 VisitedAtLeastOnce = true;
356
357 if (isa<ObjCContainerDecl>(D)) {
358 FileDI_current = &DIt;
359 FileDE_current = DE;
360 } else {
Craig Topper69186e72014-06-08 08:38:04 +0000361 FileDI_current = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +0000362 }
363
364 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000365 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000366 }
367
368 if (VisitedAtLeastOnce)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000369 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000370
371 // No Decls overlapped with the range. Move up the lexical context until there
372 // is a context that contains the range or we reach the translation unit
373 // level.
374 DeclContext *DC = DIt == Decls.begin() ? (*DIt)->getLexicalDeclContext()
375 : (*(DIt-1))->getLexicalDeclContext();
376
377 while (DC && !DC->isTranslationUnit()) {
378 Decl *D = cast<Decl>(DC);
379 SourceRange CurDeclRange = D->getSourceRange();
380 if (CurDeclRange.isInvalid())
381 break;
382
383 if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000384 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
385 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000386 }
387
388 DC = D->getLexicalDeclContext();
389 }
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000390
391 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000392}
393
394bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
395 if (!AU->getPreprocessor().getPreprocessingRecord())
396 return false;
397
398 PreprocessingRecord &PPRec
399 = *AU->getPreprocessor().getPreprocessingRecord();
400 SourceManager &SM = AU->getSourceManager();
401
402 if (RegionOfInterest.isValid()) {
403 SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
404 SourceLocation B = MappedRange.getBegin();
405 SourceLocation E = MappedRange.getEnd();
406
407 if (AU->isInPreambleFileID(B)) {
408 if (SM.isLoadedSourceLocation(E))
409 return visitPreprocessedEntitiesInRange(SourceRange(B, E),
410 PPRec, *this);
411
412 // Beginning of range lies in the preamble but it also extends beyond
413 // it into the main file. Split the range into 2 parts, one covering
414 // the preamble and another covering the main file. This allows subsequent
415 // calls to visitPreprocessedEntitiesInRange to accept a source range that
416 // lies in the same FileID, allowing it to skip preprocessed entities that
417 // do not come from the same FileID.
418 bool breaked =
419 visitPreprocessedEntitiesInRange(
420 SourceRange(B, AU->getEndOfPreambleFileID()),
421 PPRec, *this);
422 if (breaked) return true;
423 return visitPreprocessedEntitiesInRange(
424 SourceRange(AU->getStartOfMainFileID(), E),
425 PPRec, *this);
426 }
427
428 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
429 }
430
431 bool OnlyLocalDecls
432 = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
433
434 if (OnlyLocalDecls)
435 return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
436 PPRec);
437
438 return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
439}
440
441template<typename InputIterator>
442bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
443 InputIterator Last,
444 PreprocessingRecord &PPRec,
445 FileID FID) {
446 for (; First != Last; ++First) {
447 if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
448 continue;
449
450 PreprocessedEntity *PPE = *First;
Argyrios Kyrtzidis1030f262013-05-07 20:37:17 +0000451 if (!PPE)
452 continue;
453
Guy Benyei11169dd2012-12-18 14:30:41 +0000454 if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
455 if (Visit(MakeMacroExpansionCursor(ME, TU)))
456 return true;
Richard Smith66a81862015-05-04 02:25:31 +0000457
Guy Benyei11169dd2012-12-18 14:30:41 +0000458 continue;
459 }
Richard Smith66a81862015-05-04 02:25:31 +0000460
461 if (MacroDefinitionRecord *MD = dyn_cast<MacroDefinitionRecord>(PPE)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000462 if (Visit(MakeMacroDefinitionCursor(MD, TU)))
463 return true;
Richard Smith66a81862015-05-04 02:25:31 +0000464
Guy Benyei11169dd2012-12-18 14:30:41 +0000465 continue;
466 }
467
468 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
469 if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
470 return true;
471
472 continue;
473 }
474 }
475
476 return false;
477}
478
479/// \brief Visit the children of the given cursor.
480///
481/// \returns true if the visitation should be aborted, false if it
482/// should continue.
483bool CursorVisitor::VisitChildren(CXCursor Cursor) {
484 if (clang_isReference(Cursor.kind) &&
485 Cursor.kind != CXCursor_CXXBaseSpecifier) {
486 // By definition, references have no children.
487 return false;
488 }
489
490 // Set the Parent field to Cursor, then back to its old value once we're
491 // done.
492 SetParentRAII SetParent(Parent, StmtParent, Cursor);
493
494 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000495 Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +0000496 if (!D)
497 return false;
498
499 return VisitAttributes(D) || Visit(D);
500 }
501
502 if (clang_isStatement(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000503 if (const Stmt *S = getCursorStmt(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000504 return Visit(S);
505
506 return false;
507 }
508
509 if (clang_isExpression(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000510 if (const Expr *E = getCursorExpr(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000511 return Visit(E);
512
513 return false;
514 }
515
516 if (clang_isTranslationUnit(Cursor.kind)) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000517 CXTranslationUnit TU = getCursorTU(Cursor);
518 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000519
520 int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
521 for (unsigned I = 0; I != 2; ++I) {
522 if (VisitOrder[I]) {
523 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
524 RegionOfInterest.isInvalid()) {
525 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
526 TLEnd = CXXUnit->top_level_end();
527 TL != TLEnd; ++TL) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000528 if (Visit(MakeCXCursor(*TL, TU, RegionOfInterest), true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000529 return true;
530 }
531 } else if (VisitDeclContext(
532 CXXUnit->getASTContext().getTranslationUnitDecl()))
533 return true;
534 continue;
535 }
536
537 // Walk the preprocessing record.
538 if (CXXUnit->getPreprocessor().getPreprocessingRecord())
539 visitPreprocessedEntitiesInRegion();
540 }
541
542 return false;
543 }
544
545 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000546 if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000547 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
548 return Visit(BaseTSInfo->getTypeLoc());
549 }
550 }
551 }
552
553 if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +0000554 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +0000555 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
Richard Smithb1f9a282013-10-31 01:56:18 +0000556 if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())
Richard Smithb87c4652013-10-31 21:23:20 +0000557 return Visit(cxcursor::MakeCursorObjCClassRef(
558 ObjT->getInterface(),
559 A->getInterfaceLoc()->getTypeLoc().getLocStart(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +0000560 }
561
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000562 // If pointing inside a macro definition, check if the token is an identifier
563 // that was ever defined as a macro. In such a case, create a "pseudo" macro
564 // expansion cursor for that token.
565 SourceLocation BeginLoc = RegionOfInterest.getBegin();
566 if (Cursor.kind == CXCursor_MacroDefinition &&
567 BeginLoc == RegionOfInterest.getEnd()) {
568 SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000569 const MacroInfo *MI =
570 getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
Richard Smith66a81862015-05-04 02:25:31 +0000571 if (MacroDefinitionRecord *MacroDef =
572 checkForMacroInMacroDefinition(MI, Loc, TU))
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000573 return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
574 }
575
Guy Benyei11169dd2012-12-18 14:30:41 +0000576 // Nothing to visit at the moment.
577 return false;
578}
579
580bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
581 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
582 if (Visit(TSInfo->getTypeLoc()))
583 return true;
584
585 if (Stmt *Body = B->getBody())
586 return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
587
588 return false;
589}
590
Ted Kremenek03325582013-02-21 01:29:01 +0000591Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000592 if (RegionOfInterest.isValid()) {
593 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
594 if (Range.isInvalid())
David Blaikie7a30dc52013-02-21 01:47:18 +0000595 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000596
597 switch (CompareRegionOfInterest(Range)) {
598 case RangeBefore:
599 // This declaration comes before the region of interest; skip it.
David Blaikie7a30dc52013-02-21 01:47:18 +0000600 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000601
602 case RangeAfter:
603 // This declaration comes after the region of interest; we're done.
604 return false;
605
606 case RangeOverlap:
607 // This declaration overlaps the region of interest; visit it.
608 break;
609 }
610 }
611 return true;
612}
613
614bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
615 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
616
617 // FIXME: Eventually remove. This part of a hack to support proper
618 // iteration over all Decls contained lexically within an ObjC container.
619 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
620 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
621
622 for ( ; I != E; ++I) {
623 Decl *D = *I;
624 if (D->getLexicalDeclContext() != DC)
625 continue;
626 CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
627
628 // Ignore synthesized ivars here, otherwise if we have something like:
629 // @synthesize prop = _prop;
630 // and '_prop' is not declared, we will encounter a '_prop' ivar before
631 // encountering the 'prop' synthesize declaration and we will think that
632 // we passed the region-of-interest.
633 if (ObjCIvarDecl *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
634 if (ivarD->getSynthesize())
635 continue;
636 }
637
638 // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
639 // declarations is a mismatch with the compiler semantics.
640 if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
641 ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
642 if (!ID->isThisDeclarationADefinition())
643 Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
644
645 } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
646 ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
647 if (!PD->isThisDeclarationADefinition())
648 Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
649 }
650
Ted Kremenek03325582013-02-21 01:29:01 +0000651 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000652 if (!V.hasValue())
653 continue;
654 if (!V.getValue())
655 return false;
656 if (Visit(Cursor, true))
657 return true;
658 }
659 return false;
660}
661
662bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
663 llvm_unreachable("Translation units are visited directly by Visit()");
664}
665
666bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
667 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
668 return Visit(TSInfo->getTypeLoc());
669
670 return false;
671}
672
673bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
674 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
675 return Visit(TSInfo->getTypeLoc());
676
677 return false;
678}
679
680bool CursorVisitor::VisitTagDecl(TagDecl *D) {
681 return VisitDeclContext(D);
682}
683
684bool CursorVisitor::VisitClassTemplateSpecializationDecl(
685 ClassTemplateSpecializationDecl *D) {
686 bool ShouldVisitBody = false;
687 switch (D->getSpecializationKind()) {
688 case TSK_Undeclared:
689 case TSK_ImplicitInstantiation:
690 // Nothing to visit
691 return false;
692
693 case TSK_ExplicitInstantiationDeclaration:
694 case TSK_ExplicitInstantiationDefinition:
695 break;
696
697 case TSK_ExplicitSpecialization:
698 ShouldVisitBody = true;
699 break;
700 }
701
702 // Visit the template arguments used in the specialization.
703 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
704 TypeLoc TL = SpecType->getTypeLoc();
David Blaikie6adc78e2013-02-18 22:06:02 +0000705 if (TemplateSpecializationTypeLoc TSTLoc =
706 TL.getAs<TemplateSpecializationTypeLoc>()) {
707 for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
708 if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000709 return true;
710 }
711 }
712
713 if (ShouldVisitBody && VisitCXXRecordDecl(D))
714 return true;
715
716 return false;
717}
718
719bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
720 ClassTemplatePartialSpecializationDecl *D) {
721 // FIXME: Visit the "outer" template parameter lists on the TagDecl
722 // before visiting these template parameters.
723 if (VisitTemplateParameters(D->getTemplateParameters()))
724 return true;
725
726 // Visit the partial specialization arguments.
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000727 const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
728 const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
729 for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
Guy Benyei11169dd2012-12-18 14:30:41 +0000730 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
731 return true;
732
733 return VisitCXXRecordDecl(D);
734}
735
736bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
737 // Visit the default argument.
738 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
739 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
740 if (Visit(DefArg->getTypeLoc()))
741 return true;
742
743 return false;
744}
745
746bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
747 if (Expr *Init = D->getInitExpr())
748 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
749 return false;
750}
751
752bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000753 unsigned NumParamList = DD->getNumTemplateParameterLists();
754 for (unsigned i = 0; i < NumParamList; i++) {
755 TemplateParameterList* Params = DD->getTemplateParameterList(i);
756 if (VisitTemplateParameters(Params))
757 return true;
758 }
759
Guy Benyei11169dd2012-12-18 14:30:41 +0000760 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
761 if (Visit(TSInfo->getTypeLoc()))
762 return true;
763
764 // Visit the nested-name-specifier, if present.
765 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
766 if (VisitNestedNameSpecifierLoc(QualifierLoc))
767 return true;
768
769 return false;
770}
771
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000772/// \brief Compare two base or member initializers based on their source order.
773static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
774 CXXCtorInitializer *const *Y) {
775 return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
776}
777
Guy Benyei11169dd2012-12-18 14:30:41 +0000778bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000779 unsigned NumParamList = ND->getNumTemplateParameterLists();
780 for (unsigned i = 0; i < NumParamList; i++) {
781 TemplateParameterList* Params = ND->getTemplateParameterList(i);
782 if (VisitTemplateParameters(Params))
783 return true;
784 }
785
Guy Benyei11169dd2012-12-18 14:30:41 +0000786 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
787 // Visit the function declaration's syntactic components in the order
788 // written. This requires a bit of work.
789 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
David Blaikie6adc78e2013-02-18 22:06:02 +0000790 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Guy Benyei11169dd2012-12-18 14:30:41 +0000791
792 // If we have a function declared directly (without the use of a typedef),
793 // visit just the return type. Otherwise, just visit the function's type
794 // now.
Alp Toker42a16a62014-01-25 23:51:36 +0000795 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getReturnLoc())) ||
Guy Benyei11169dd2012-12-18 14:30:41 +0000796 (!FTL && Visit(TL)))
797 return true;
798
799 // Visit the nested-name-specifier, if present.
800 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
801 if (VisitNestedNameSpecifierLoc(QualifierLoc))
802 return true;
803
804 // Visit the declaration name.
Argyrios Kyrtzidis4a4d2b42014-02-09 08:13:47 +0000805 if (!isa<CXXDestructorDecl>(ND))
806 if (VisitDeclarationNameInfo(ND->getNameInfo()))
807 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +0000808
809 // FIXME: Visit explicitly-specified template arguments!
810
811 // Visit the function parameters, if we have a function type.
David Blaikie6adc78e2013-02-18 22:06:02 +0000812 if (FTL && VisitFunctionTypeLoc(FTL, true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000813 return true;
814
Bill Wendling44426052012-12-20 19:22:21 +0000815 // FIXME: Attributes?
Guy Benyei11169dd2012-12-18 14:30:41 +0000816 }
817
818 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
819 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
820 // Find the initializers that were written in the source.
821 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
Aaron Ballman0ad78302014-03-13 17:34:31 +0000822 for (auto *I : Constructor->inits()) {
823 if (!I->isWritten())
Guy Benyei11169dd2012-12-18 14:30:41 +0000824 continue;
825
Aaron Ballman0ad78302014-03-13 17:34:31 +0000826 WrittenInits.push_back(I);
Guy Benyei11169dd2012-12-18 14:30:41 +0000827 }
828
829 // Sort the initializers in source order
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000830 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
831 &CompareCXXCtorInitializers);
832
Guy Benyei11169dd2012-12-18 14:30:41 +0000833 // Visit the initializers in source order
834 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
835 CXXCtorInitializer *Init = WrittenInits[I];
836 if (Init->isAnyMemberInitializer()) {
837 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
838 Init->getMemberLocation(), TU)))
839 return true;
840 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
841 if (Visit(TInfo->getTypeLoc()))
842 return true;
843 }
844
845 // Visit the initializer value.
846 if (Expr *Initializer = Init->getInit())
847 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
848 return true;
849 }
850 }
851
852 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
853 return true;
854 }
855
856 return false;
857}
858
859bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
860 if (VisitDeclaratorDecl(D))
861 return true;
862
863 if (Expr *BitWidth = D->getBitWidth())
864 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
865
866 return false;
867}
868
869bool CursorVisitor::VisitVarDecl(VarDecl *D) {
870 if (VisitDeclaratorDecl(D))
871 return true;
872
873 if (Expr *Init = D->getInit())
874 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
875
876 return false;
877}
878
879bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
880 if (VisitDeclaratorDecl(D))
881 return true;
882
883 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
884 if (Expr *DefArg = D->getDefaultArgument())
885 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
886
887 return false;
888}
889
890bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
891 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
892 // before visiting these template parameters.
893 if (VisitTemplateParameters(D->getTemplateParameters()))
894 return true;
895
896 return VisitFunctionDecl(D->getTemplatedDecl());
897}
898
899bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
900 // FIXME: Visit the "outer" template parameter lists on the TagDecl
901 // before visiting these template parameters.
902 if (VisitTemplateParameters(D->getTemplateParameters()))
903 return true;
904
905 return VisitCXXRecordDecl(D->getTemplatedDecl());
906}
907
908bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
909 if (VisitTemplateParameters(D->getTemplateParameters()))
910 return true;
911
912 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
913 VisitTemplateArgumentLoc(D->getDefaultArgument()))
914 return true;
915
916 return false;
917}
918
919bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Alp Toker314cc812014-01-25 16:55:45 +0000920 if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
Guy Benyei11169dd2012-12-18 14:30:41 +0000921 if (Visit(TSInfo->getTypeLoc()))
922 return true;
923
Aaron Ballman43b68be2014-03-07 17:50:17 +0000924 for (const auto *P : ND->params()) {
925 if (Visit(MakeCXCursor(P, TU, RegionOfInterest)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000926 return true;
927 }
928
929 if (ND->isThisDeclarationADefinition() &&
930 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
931 return true;
932
933 return false;
934}
935
936template <typename DeclIt>
937static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
938 SourceManager &SM, SourceLocation EndLoc,
939 SmallVectorImpl<Decl *> &Decls) {
940 DeclIt next = *DI_current;
941 while (++next != DE_current) {
942 Decl *D_next = *next;
943 if (!D_next)
944 break;
945 SourceLocation L = D_next->getLocStart();
946 if (!L.isValid())
947 break;
948 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
949 *DI_current = next;
950 Decls.push_back(D_next);
951 continue;
952 }
953 break;
954 }
955}
956
Guy Benyei11169dd2012-12-18 14:30:41 +0000957bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
958 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
959 // an @implementation can lexically contain Decls that are not properly
960 // nested in the AST. When we identify such cases, we need to retrofit
961 // this nesting here.
962 if (!DI_current && !FileDI_current)
963 return VisitDeclContext(D);
964
965 // Scan the Decls that immediately come after the container
966 // in the current DeclContext. If any fall within the
967 // container's lexical region, stash them into a vector
968 // for later processing.
969 SmallVector<Decl *, 24> DeclsInContainer;
970 SourceLocation EndLoc = D->getSourceRange().getEnd();
971 SourceManager &SM = AU->getSourceManager();
972 if (EndLoc.isValid()) {
973 if (DI_current) {
974 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
975 DeclsInContainer);
976 } else {
977 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
978 DeclsInContainer);
979 }
980 }
981
982 // The common case.
983 if (DeclsInContainer.empty())
984 return VisitDeclContext(D);
985
986 // Get all the Decls in the DeclContext, and sort them with the
987 // additional ones we've collected. Then visit them.
Aaron Ballman629afae2014-03-07 19:56:05 +0000988 for (auto *SubDecl : D->decls()) {
989 if (!SubDecl || SubDecl->getLexicalDeclContext() != D ||
990 SubDecl->getLocStart().isInvalid())
Guy Benyei11169dd2012-12-18 14:30:41 +0000991 continue;
Aaron Ballman629afae2014-03-07 19:56:05 +0000992 DeclsInContainer.push_back(SubDecl);
Guy Benyei11169dd2012-12-18 14:30:41 +0000993 }
994
995 // Now sort the Decls so that they appear in lexical order.
996 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
Benjamin Kramerbbdd7642014-03-01 14:48:57 +0000997 [&SM](Decl *A, Decl *B) {
998 SourceLocation L_A = A->getLocStart();
999 SourceLocation L_B = B->getLocStart();
1000 assert(L_A.isValid() && L_B.isValid());
1001 return SM.isBeforeInTranslationUnit(L_A, L_B);
1002 });
Guy Benyei11169dd2012-12-18 14:30:41 +00001003
1004 // Now visit the decls.
1005 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
1006 E = DeclsInContainer.end(); I != E; ++I) {
1007 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek03325582013-02-21 01:29:01 +00001008 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00001009 if (!V.hasValue())
1010 continue;
1011 if (!V.getValue())
1012 return false;
1013 if (Visit(Cursor, true))
1014 return true;
1015 }
1016 return false;
1017}
1018
1019bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1020 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1021 TU)))
1022 return true;
1023
1024 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1025 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1026 E = ND->protocol_end(); I != E; ++I, ++PL)
1027 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1028 return true;
1029
1030 return VisitObjCContainerDecl(ND);
1031}
1032
1033bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1034 if (!PID->isThisDeclarationADefinition())
1035 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1036
1037 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1038 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1039 E = PID->protocol_end(); I != E; ++I, ++PL)
1040 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1041 return true;
1042
1043 return VisitObjCContainerDecl(PID);
1044}
1045
1046bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1047 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1048 return true;
1049
1050 // FIXME: This implements a workaround with @property declarations also being
1051 // installed in the DeclContext for the @interface. Eventually this code
1052 // should be removed.
1053 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1054 if (!CDecl || !CDecl->IsClassExtension())
1055 return false;
1056
1057 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1058 if (!ID)
1059 return false;
1060
1061 IdentifierInfo *PropertyId = PD->getIdentifier();
1062 ObjCPropertyDecl *prevDecl =
1063 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1064
1065 if (!prevDecl)
1066 return false;
1067
1068 // Visit synthesized methods since they will be skipped when visiting
1069 // the @interface.
1070 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1071 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1072 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1073 return true;
1074
1075 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1076 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1077 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1078 return true;
1079
1080 return false;
1081}
1082
1083bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1084 if (!D->isThisDeclarationADefinition()) {
1085 // Forward declaration is treated like a reference.
1086 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1087 }
1088
1089 // Issue callbacks for super class.
1090 if (D->getSuperClass() &&
1091 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1092 D->getSuperClassLoc(),
1093 TU)))
1094 return true;
1095
1096 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1097 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1098 E = D->protocol_end(); I != E; ++I, ++PL)
1099 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1100 return true;
1101
1102 return VisitObjCContainerDecl(D);
1103}
1104
1105bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1106 return VisitObjCContainerDecl(D);
1107}
1108
1109bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1110 // 'ID' could be null when dealing with invalid code.
1111 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1112 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1113 return true;
1114
1115 return VisitObjCImplDecl(D);
1116}
1117
1118bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1119#if 0
1120 // Issue callbacks for super class.
1121 // FIXME: No source location information!
1122 if (D->getSuperClass() &&
1123 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1124 D->getSuperClassLoc(),
1125 TU)))
1126 return true;
1127#endif
1128
1129 return VisitObjCImplDecl(D);
1130}
1131
1132bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1133 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1134 if (PD->isIvarNameSpecified())
1135 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1136
1137 return false;
1138}
1139
1140bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1141 return VisitDeclContext(D);
1142}
1143
1144bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1145 // Visit nested-name-specifier.
1146 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1147 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1148 return true;
1149
1150 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1151 D->getTargetNameLoc(), TU));
1152}
1153
1154bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1155 // Visit nested-name-specifier.
1156 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1157 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1158 return true;
1159 }
1160
1161 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1162 return true;
1163
1164 return VisitDeclarationNameInfo(D->getNameInfo());
1165}
1166
1167bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1168 // Visit nested-name-specifier.
1169 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1170 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1171 return true;
1172
1173 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1174 D->getIdentLocation(), TU));
1175}
1176
1177bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1178 // Visit nested-name-specifier.
1179 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1180 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1181 return true;
1182 }
1183
1184 return VisitDeclarationNameInfo(D->getNameInfo());
1185}
1186
1187bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1188 UnresolvedUsingTypenameDecl *D) {
1189 // Visit nested-name-specifier.
1190 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1191 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1192 return true;
1193
1194 return false;
1195}
1196
1197bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1198 switch (Name.getName().getNameKind()) {
1199 case clang::DeclarationName::Identifier:
1200 case clang::DeclarationName::CXXLiteralOperatorName:
1201 case clang::DeclarationName::CXXOperatorName:
1202 case clang::DeclarationName::CXXUsingDirective:
1203 return false;
1204
1205 case clang::DeclarationName::CXXConstructorName:
1206 case clang::DeclarationName::CXXDestructorName:
1207 case clang::DeclarationName::CXXConversionFunctionName:
1208 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1209 return Visit(TSInfo->getTypeLoc());
1210 return false;
1211
1212 case clang::DeclarationName::ObjCZeroArgSelector:
1213 case clang::DeclarationName::ObjCOneArgSelector:
1214 case clang::DeclarationName::ObjCMultiArgSelector:
1215 // FIXME: Per-identifier location info?
1216 return false;
1217 }
1218
1219 llvm_unreachable("Invalid DeclarationName::Kind!");
1220}
1221
1222bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1223 SourceRange Range) {
1224 // FIXME: This whole routine is a hack to work around the lack of proper
1225 // source information in nested-name-specifiers (PR5791). Since we do have
1226 // a beginning source location, we can visit the first component of the
1227 // nested-name-specifier, if it's a single-token component.
1228 if (!NNS)
1229 return false;
1230
1231 // Get the first component in the nested-name-specifier.
1232 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1233 NNS = Prefix;
1234
1235 switch (NNS->getKind()) {
1236 case NestedNameSpecifier::Namespace:
1237 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1238 TU));
1239
1240 case NestedNameSpecifier::NamespaceAlias:
1241 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1242 Range.getBegin(), TU));
1243
1244 case NestedNameSpecifier::TypeSpec: {
1245 // If the type has a form where we know that the beginning of the source
1246 // range matches up with a reference cursor. Visit the appropriate reference
1247 // cursor.
1248 const Type *T = NNS->getAsType();
1249 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1250 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1251 if (const TagType *Tag = dyn_cast<TagType>(T))
1252 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1253 if (const TemplateSpecializationType *TST
1254 = dyn_cast<TemplateSpecializationType>(T))
1255 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1256 break;
1257 }
1258
1259 case NestedNameSpecifier::TypeSpecWithTemplate:
1260 case NestedNameSpecifier::Global:
1261 case NestedNameSpecifier::Identifier:
Nikola Smiljanic67860242014-09-26 00:28:20 +00001262 case NestedNameSpecifier::Super:
Guy Benyei11169dd2012-12-18 14:30:41 +00001263 break;
1264 }
1265
1266 return false;
1267}
1268
1269bool
1270CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1271 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1272 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1273 Qualifiers.push_back(Qualifier);
1274
1275 while (!Qualifiers.empty()) {
1276 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1277 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1278 switch (NNS->getKind()) {
1279 case NestedNameSpecifier::Namespace:
1280 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1281 Q.getLocalBeginLoc(),
1282 TU)))
1283 return true;
1284
1285 break;
1286
1287 case NestedNameSpecifier::NamespaceAlias:
1288 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1289 Q.getLocalBeginLoc(),
1290 TU)))
1291 return true;
1292
1293 break;
1294
1295 case NestedNameSpecifier::TypeSpec:
1296 case NestedNameSpecifier::TypeSpecWithTemplate:
1297 if (Visit(Q.getTypeLoc()))
1298 return true;
1299
1300 break;
1301
1302 case NestedNameSpecifier::Global:
1303 case NestedNameSpecifier::Identifier:
Nikola Smiljanic67860242014-09-26 00:28:20 +00001304 case NestedNameSpecifier::Super:
Guy Benyei11169dd2012-12-18 14:30:41 +00001305 break;
1306 }
1307 }
1308
1309 return false;
1310}
1311
1312bool CursorVisitor::VisitTemplateParameters(
1313 const TemplateParameterList *Params) {
1314 if (!Params)
1315 return false;
1316
1317 for (TemplateParameterList::const_iterator P = Params->begin(),
1318 PEnd = Params->end();
1319 P != PEnd; ++P) {
1320 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1321 return true;
1322 }
1323
1324 return false;
1325}
1326
1327bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1328 switch (Name.getKind()) {
1329 case TemplateName::Template:
1330 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1331
1332 case TemplateName::OverloadedTemplate:
1333 // Visit the overloaded template set.
1334 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1335 return true;
1336
1337 return false;
1338
1339 case TemplateName::DependentTemplate:
1340 // FIXME: Visit nested-name-specifier.
1341 return false;
1342
1343 case TemplateName::QualifiedTemplate:
1344 // FIXME: Visit nested-name-specifier.
1345 return Visit(MakeCursorTemplateRef(
1346 Name.getAsQualifiedTemplateName()->getDecl(),
1347 Loc, TU));
1348
1349 case TemplateName::SubstTemplateTemplateParm:
1350 return Visit(MakeCursorTemplateRef(
1351 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1352 Loc, TU));
1353
1354 case TemplateName::SubstTemplateTemplateParmPack:
1355 return Visit(MakeCursorTemplateRef(
1356 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1357 Loc, TU));
1358 }
1359
1360 llvm_unreachable("Invalid TemplateName::Kind!");
1361}
1362
1363bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1364 switch (TAL.getArgument().getKind()) {
1365 case TemplateArgument::Null:
1366 case TemplateArgument::Integral:
1367 case TemplateArgument::Pack:
1368 return false;
1369
1370 case TemplateArgument::Type:
1371 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1372 return Visit(TSInfo->getTypeLoc());
1373 return false;
1374
1375 case TemplateArgument::Declaration:
1376 if (Expr *E = TAL.getSourceDeclExpression())
1377 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1378 return false;
1379
1380 case TemplateArgument::NullPtr:
1381 if (Expr *E = TAL.getSourceNullPtrExpression())
1382 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1383 return false;
1384
1385 case TemplateArgument::Expression:
1386 if (Expr *E = TAL.getSourceExpression())
1387 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1388 return false;
1389
1390 case TemplateArgument::Template:
1391 case TemplateArgument::TemplateExpansion:
1392 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1393 return true;
1394
1395 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1396 TAL.getTemplateNameLoc());
1397 }
1398
1399 llvm_unreachable("Invalid TemplateArgument::Kind!");
1400}
1401
1402bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1403 return VisitDeclContext(D);
1404}
1405
1406bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1407 return Visit(TL.getUnqualifiedLoc());
1408}
1409
1410bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1411 ASTContext &Context = AU->getASTContext();
1412
1413 // Some builtin types (such as Objective-C's "id", "sel", and
1414 // "Class") have associated declarations. Create cursors for those.
1415 QualType VisitType;
1416 switch (TL.getTypePtr()->getKind()) {
1417
1418 case BuiltinType::Void:
1419 case BuiltinType::NullPtr:
1420 case BuiltinType::Dependent:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001421 case BuiltinType::OCLImage1d:
1422 case BuiltinType::OCLImage1dArray:
1423 case BuiltinType::OCLImage1dBuffer:
1424 case BuiltinType::OCLImage2d:
1425 case BuiltinType::OCLImage2dArray:
1426 case BuiltinType::OCLImage3d:
NAKAMURA Takumi288c42e2013-02-07 12:47:42 +00001427 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +00001428 case BuiltinType::OCLEvent:
Guy Benyei11169dd2012-12-18 14:30:41 +00001429#define BUILTIN_TYPE(Id, SingletonId)
1430#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1431#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1432#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1433#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1434#include "clang/AST/BuiltinTypes.def"
1435 break;
1436
1437 case BuiltinType::ObjCId:
1438 VisitType = Context.getObjCIdType();
1439 break;
1440
1441 case BuiltinType::ObjCClass:
1442 VisitType = Context.getObjCClassType();
1443 break;
1444
1445 case BuiltinType::ObjCSel:
1446 VisitType = Context.getObjCSelType();
1447 break;
1448 }
1449
1450 if (!VisitType.isNull()) {
1451 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1452 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1453 TU));
1454 }
1455
1456 return false;
1457}
1458
1459bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1460 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1461}
1462
1463bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1464 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1465}
1466
1467bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1468 if (TL.isDefinition())
1469 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1470
1471 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1472}
1473
1474bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1475 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1476}
1477
1478bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1479 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1480 return true;
1481
1482 return false;
1483}
1484
1485bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1486 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1487 return true;
1488
1489 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1490 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1491 TU)))
1492 return true;
1493 }
1494
1495 return false;
1496}
1497
1498bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1499 return Visit(TL.getPointeeLoc());
1500}
1501
1502bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1503 return Visit(TL.getInnerLoc());
1504}
1505
1506bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1507 return Visit(TL.getPointeeLoc());
1508}
1509
1510bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1511 return Visit(TL.getPointeeLoc());
1512}
1513
1514bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1515 return Visit(TL.getPointeeLoc());
1516}
1517
1518bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1519 return Visit(TL.getPointeeLoc());
1520}
1521
1522bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1523 return Visit(TL.getPointeeLoc());
1524}
1525
1526bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1527 return Visit(TL.getModifiedLoc());
1528}
1529
1530bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1531 bool SkipResultType) {
Alp Toker42a16a62014-01-25 23:51:36 +00001532 if (!SkipResultType && Visit(TL.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001533 return true;
1534
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00001535 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1536 if (Decl *D = TL.getParam(I))
Guy Benyei11169dd2012-12-18 14:30:41 +00001537 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1538 return true;
1539
1540 return false;
1541}
1542
1543bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1544 if (Visit(TL.getElementLoc()))
1545 return true;
1546
1547 if (Expr *Size = TL.getSizeExpr())
1548 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1549
1550 return false;
1551}
1552
Reid Kleckner8a365022013-06-24 17:51:48 +00001553bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1554 return Visit(TL.getOriginalLoc());
1555}
1556
Reid Kleckner0503a872013-12-05 01:23:43 +00001557bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1558 return Visit(TL.getOriginalLoc());
1559}
1560
Guy Benyei11169dd2012-12-18 14:30:41 +00001561bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1562 TemplateSpecializationTypeLoc TL) {
1563 // Visit the template name.
1564 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1565 TL.getTemplateNameLoc()))
1566 return true;
1567
1568 // Visit the template arguments.
1569 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1570 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1571 return true;
1572
1573 return false;
1574}
1575
1576bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1577 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1578}
1579
1580bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1581 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1582 return Visit(TSInfo->getTypeLoc());
1583
1584 return false;
1585}
1586
1587bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1588 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1589 return Visit(TSInfo->getTypeLoc());
1590
1591 return false;
1592}
1593
1594bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1595 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1596 return true;
1597
1598 return false;
1599}
1600
1601bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1602 DependentTemplateSpecializationTypeLoc TL) {
1603 // Visit the nested-name-specifier, if there is one.
1604 if (TL.getQualifierLoc() &&
1605 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1606 return true;
1607
1608 // Visit the template arguments.
1609 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1610 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1611 return true;
1612
1613 return false;
1614}
1615
1616bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1617 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1618 return true;
1619
1620 return Visit(TL.getNamedTypeLoc());
1621}
1622
1623bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1624 return Visit(TL.getPatternLoc());
1625}
1626
1627bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1628 if (Expr *E = TL.getUnderlyingExpr())
1629 return Visit(MakeCXCursor(E, StmtParent, TU));
1630
1631 return false;
1632}
1633
1634bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1635 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1636}
1637
1638bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1639 return Visit(TL.getValueLoc());
1640}
1641
1642#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1643bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1644 return Visit##PARENT##Loc(TL); \
1645}
1646
1647DEFAULT_TYPELOC_IMPL(Complex, Type)
1648DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1649DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1650DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1651DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1652DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1653DEFAULT_TYPELOC_IMPL(Vector, Type)
1654DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1655DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1656DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1657DEFAULT_TYPELOC_IMPL(Record, TagType)
1658DEFAULT_TYPELOC_IMPL(Enum, TagType)
1659DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1660DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1661DEFAULT_TYPELOC_IMPL(Auto, Type)
1662
1663bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1664 // Visit the nested-name-specifier, if present.
1665 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1666 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1667 return true;
1668
1669 if (D->isCompleteDefinition()) {
Aaron Ballman574705e2014-03-13 15:41:46 +00001670 for (const auto &I : D->bases()) {
1671 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001672 return true;
1673 }
1674 }
1675
1676 return VisitTagDecl(D);
1677}
1678
1679bool CursorVisitor::VisitAttributes(Decl *D) {
Aaron Ballmanb97112e2014-03-08 22:19:01 +00001680 for (const auto *I : D->attrs())
1681 if (Visit(MakeCXCursor(I, D, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001682 return true;
1683
1684 return false;
1685}
1686
1687//===----------------------------------------------------------------------===//
1688// Data-recursive visitor methods.
1689//===----------------------------------------------------------------------===//
1690
1691namespace {
1692#define DEF_JOB(NAME, DATA, KIND)\
1693class NAME : public VisitorJob {\
1694public:\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001695 NAME(const DATA *d, CXCursor parent) : \
1696 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei11169dd2012-12-18 14:30:41 +00001697 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001698 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei11169dd2012-12-18 14:30:41 +00001699};
1700
1701DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1702DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1703DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1704DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1705DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1706 ExplicitTemplateArgsVisitKind)
1707DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1708DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1709DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1710#undef DEF_JOB
1711
1712class DeclVisit : public VisitorJob {
1713public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001714 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei11169dd2012-12-18 14:30:41 +00001715 VisitorJob(parent, VisitorJob::DeclVisitKind,
Craig Topper69186e72014-06-08 08:38:04 +00001716 D, isFirst ? (void*) 1 : (void*) nullptr) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001717 static bool classof(const VisitorJob *VJ) {
1718 return VJ->getKind() == DeclVisitKind;
1719 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001720 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Dmitri Gribenkoe5423a72015-03-23 19:23:50 +00001721 bool isFirst() const { return data[1] != nullptr; }
Guy Benyei11169dd2012-12-18 14:30:41 +00001722};
1723class TypeLocVisit : public VisitorJob {
1724public:
1725 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1726 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1727 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1728
1729 static bool classof(const VisitorJob *VJ) {
1730 return VJ->getKind() == TypeLocVisitKind;
1731 }
1732
1733 TypeLoc get() const {
1734 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001735 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001736 }
1737};
1738
1739class LabelRefVisit : public VisitorJob {
1740public:
1741 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1742 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1743 labelLoc.getPtrEncoding()) {}
1744
1745 static bool classof(const VisitorJob *VJ) {
1746 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1747 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001748 const LabelDecl *get() const {
1749 return static_cast<const LabelDecl *>(data[0]);
1750 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001751 SourceLocation getLoc() const {
1752 return SourceLocation::getFromPtrEncoding(data[1]); }
1753};
1754
1755class NestedNameSpecifierLocVisit : public VisitorJob {
1756public:
1757 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1758 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1759 Qualifier.getNestedNameSpecifier(),
1760 Qualifier.getOpaqueData()) { }
1761
1762 static bool classof(const VisitorJob *VJ) {
1763 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1764 }
1765
1766 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001767 return NestedNameSpecifierLoc(
1768 const_cast<NestedNameSpecifier *>(
1769 static_cast<const NestedNameSpecifier *>(data[0])),
1770 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001771 }
1772};
1773
1774class DeclarationNameInfoVisit : public VisitorJob {
1775public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001776 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001777 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001778 static bool classof(const VisitorJob *VJ) {
1779 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1780 }
1781 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001782 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001783 switch (S->getStmtClass()) {
1784 default:
1785 llvm_unreachable("Unhandled Stmt");
1786 case clang::Stmt::MSDependentExistsStmtClass:
1787 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1788 case Stmt::CXXDependentScopeMemberExprClass:
1789 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1790 case Stmt::DependentScopeDeclRefExprClass:
1791 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001792 case Stmt::OMPCriticalDirectiveClass:
1793 return cast<OMPCriticalDirective>(S)->getDirectiveName();
Guy Benyei11169dd2012-12-18 14:30:41 +00001794 }
1795 }
1796};
1797class MemberRefVisit : public VisitorJob {
1798public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001799 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei11169dd2012-12-18 14:30:41 +00001800 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1801 L.getPtrEncoding()) {}
1802 static bool classof(const VisitorJob *VJ) {
1803 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1804 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001805 const FieldDecl *get() const {
1806 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001807 }
1808 SourceLocation getLoc() const {
1809 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1810 }
1811};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001812class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001813 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001814 VisitorWorkList &WL;
1815 CXCursor Parent;
1816public:
1817 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1818 : WL(wl), Parent(parent) {}
1819
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001820 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1821 void VisitBlockExpr(const BlockExpr *B);
1822 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1823 void VisitCompoundStmt(const CompoundStmt *S);
1824 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1825 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1826 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1827 void VisitCXXNewExpr(const CXXNewExpr *E);
1828 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1829 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1830 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1831 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1832 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1833 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1834 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1835 void VisitCXXCatchStmt(const CXXCatchStmt *S);
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00001836 void VisitCXXForRangeStmt(const CXXForRangeStmt *S);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001837 void VisitDeclRefExpr(const DeclRefExpr *D);
1838 void VisitDeclStmt(const DeclStmt *S);
1839 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1840 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1841 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1842 void VisitForStmt(const ForStmt *FS);
1843 void VisitGotoStmt(const GotoStmt *GS);
1844 void VisitIfStmt(const IfStmt *If);
1845 void VisitInitListExpr(const InitListExpr *IE);
1846 void VisitMemberExpr(const MemberExpr *M);
1847 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1848 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1849 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1850 void VisitOverloadExpr(const OverloadExpr *E);
1851 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1852 void VisitStmt(const Stmt *S);
1853 void VisitSwitchStmt(const SwitchStmt *S);
1854 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001855 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1856 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1857 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1858 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1859 void VisitVAArgExpr(const VAArgExpr *E);
1860 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1861 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1862 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1863 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001864 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
Alexander Musman3aaab662014-08-19 11:27:13 +00001865 void VisitOMPLoopDirective(const OMPLoopDirective *D);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001866 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00001867 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00001868 void VisitOMPForDirective(const OMPForDirective *D);
Alexander Musmanf82886e2014-09-18 05:12:34 +00001869 void VisitOMPForSimdDirective(const OMPForSimdDirective *D);
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00001870 void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
Alexey Bataev1e0498a2014-06-26 08:21:58 +00001871 void VisitOMPSectionDirective(const OMPSectionDirective *D);
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00001872 void VisitOMPSingleDirective(const OMPSingleDirective *D);
Alexander Musman80c22892014-07-17 08:54:58 +00001873 void VisitOMPMasterDirective(const OMPMasterDirective *D);
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001874 void VisitOMPCriticalDirective(const OMPCriticalDirective *D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00001875 void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
Alexander Musmane4e893b2014-09-23 09:33:00 +00001876 void VisitOMPParallelForSimdDirective(const OMPParallelForSimdDirective *D);
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00001877 void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective *D);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00001878 void VisitOMPTaskDirective(const OMPTaskDirective *D);
Alexey Bataev68446b72014-07-18 07:47:19 +00001879 void VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D);
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00001880 void VisitOMPBarrierDirective(const OMPBarrierDirective *D);
Alexey Bataev2df347a2014-07-18 10:17:07 +00001881 void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00001882 void VisitOMPTaskgroupDirective(const OMPTaskgroupDirective *D);
Alexey Bataev6125da92014-07-21 11:26:11 +00001883 void VisitOMPFlushDirective(const OMPFlushDirective *D);
Alexey Bataev9fb6e642014-07-22 06:45:04 +00001884 void VisitOMPOrderedDirective(const OMPOrderedDirective *D);
Alexey Bataev0162e452014-07-22 10:10:35 +00001885 void VisitOMPAtomicDirective(const OMPAtomicDirective *D);
Alexey Bataev0bd520b2014-09-19 08:19:49 +00001886 void VisitOMPTargetDirective(const OMPTargetDirective *D);
Alexey Bataev13314bf2014-10-09 04:18:56 +00001887 void VisitOMPTeamsDirective(const OMPTeamsDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001888
Guy Benyei11169dd2012-12-18 14:30:41 +00001889private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001890 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001891 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1892 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001893 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1894 void AddStmt(const Stmt *S);
1895 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001896 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001897 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001898 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001899};
1900} // end anonyous namespace
1901
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001902void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001903 // 'S' should always be non-null, since it comes from the
1904 // statement we are visiting.
1905 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1906}
1907
1908void
1909EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1910 if (Qualifier)
1911 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1912}
1913
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001914void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001915 if (S)
1916 WL.push_back(StmtVisit(S, Parent));
1917}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001918void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001919 if (D)
1920 WL.push_back(DeclVisit(D, Parent, isFirst));
1921}
1922void EnqueueVisitor::
1923 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1924 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001925 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001926}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001927void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001928 if (D)
1929 WL.push_back(MemberRefVisit(D, L, Parent));
1930}
1931void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1932 if (TI)
1933 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1934 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001935void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001936 unsigned size = WL.size();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001937 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001938 AddStmt(*Child);
1939 }
1940 if (size == WL.size())
1941 return;
1942 // Now reverse the entries we just added. This will match the DFS
1943 // ordering performed by the worklist.
1944 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1945 std::reverse(I, E);
1946}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001947namespace {
1948class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1949 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001950 /// \brief Process clauses with list of variables.
1951 template <typename T>
1952 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001953public:
1954 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1955#define OPENMP_CLAUSE(Name, Class) \
1956 void Visit##Class(const Class *C);
1957#include "clang/Basic/OpenMPKinds.def"
1958};
1959
Alexey Bataevaadd52e2014-02-13 05:29:23 +00001960void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
1961 Visitor->AddStmt(C->getCondition());
1962}
1963
Alexey Bataev3778b602014-07-17 07:32:53 +00001964void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
1965 Visitor->AddStmt(C->getCondition());
1966}
1967
Alexey Bataev568a8332014-03-06 06:15:19 +00001968void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
1969 Visitor->AddStmt(C->getNumThreads());
1970}
1971
Alexey Bataev62c87d22014-03-21 04:51:18 +00001972void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
1973 Visitor->AddStmt(C->getSafelen());
1974}
1975
Alexander Musman8bd31e62014-05-27 15:12:19 +00001976void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
1977 Visitor->AddStmt(C->getNumForLoops());
1978}
1979
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001980void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00001981
Alexey Bataevbcbadb62014-05-06 06:04:14 +00001982void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
1983
Alexey Bataev56dafe82014-06-20 07:16:17 +00001984void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
1985 Visitor->AddStmt(C->getChunkSize());
Alexey Bataev040d5402015-05-12 08:35:28 +00001986 Visitor->AddStmt(C->getHelperChunkSize());
Alexey Bataev56dafe82014-06-20 07:16:17 +00001987}
1988
Alexey Bataev142e1fc2014-06-20 09:44:06 +00001989void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *) {}
1990
Alexey Bataev236070f2014-06-20 11:19:47 +00001991void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
1992
Alexey Bataev7aea99a2014-07-17 12:19:31 +00001993void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
1994
Alexey Bataev74ba3a52014-07-17 12:47:03 +00001995void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
1996
Alexey Bataevf98b00c2014-07-23 02:27:21 +00001997void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}
1998
Alexey Bataevdea47612014-07-23 07:46:59 +00001999void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {}
2000
Alexey Bataev67a4f222014-07-23 10:25:33 +00002001void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {}
2002
Alexey Bataev459dec02014-07-24 06:46:57 +00002003void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}
2004
Alexey Bataev82bad8b2014-07-24 08:55:34 +00002005void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
2006
Alexey Bataev756c1962013-09-24 03:17:45 +00002007template<typename T>
2008void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Alexey Bataev03b340a2014-10-21 03:16:40 +00002009 for (const auto *I : Node->varlists()) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00002010 Visitor->AddStmt(I);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002011 }
Alexey Bataev756c1962013-09-24 03:17:45 +00002012}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002013
2014void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002015 VisitOMPClauseList(C);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002016 for (const auto *E : C->private_copies()) {
2017 Visitor->AddStmt(E);
2018 }
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002019}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002020void OMPClauseEnqueue::VisitOMPFirstprivateClause(
2021 const OMPFirstprivateClause *C) {
2022 VisitOMPClauseList(C);
2023}
Alexander Musman1bb328c2014-06-04 13:06:39 +00002024void OMPClauseEnqueue::VisitOMPLastprivateClause(
2025 const OMPLastprivateClause *C) {
2026 VisitOMPClauseList(C);
Alexey Bataev38e89532015-04-16 04:54:05 +00002027 for (auto *E : C->private_copies()) {
2028 Visitor->AddStmt(E);
2029 }
2030 for (auto *E : C->source_exprs()) {
2031 Visitor->AddStmt(E);
2032 }
2033 for (auto *E : C->destination_exprs()) {
2034 Visitor->AddStmt(E);
2035 }
2036 for (auto *E : C->assignment_ops()) {
2037 Visitor->AddStmt(E);
2038 }
Alexander Musman1bb328c2014-06-04 13:06:39 +00002039}
Alexey Bataev758e55e2013-09-06 18:03:48 +00002040void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002041 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00002042}
Alexey Bataevc5e02582014-06-16 07:08:35 +00002043void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
2044 VisitOMPClauseList(C);
Alexey Bataev794ba0d2015-04-10 10:43:45 +00002045 for (auto *E : C->lhs_exprs()) {
2046 Visitor->AddStmt(E);
2047 }
2048 for (auto *E : C->rhs_exprs()) {
2049 Visitor->AddStmt(E);
2050 }
2051 for (auto *E : C->reduction_ops()) {
2052 Visitor->AddStmt(E);
2053 }
Alexey Bataevc5e02582014-06-16 07:08:35 +00002054}
Alexander Musman8dba6642014-04-22 13:09:42 +00002055void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2056 VisitOMPClauseList(C);
Alexander Musman3276a272015-03-21 10:12:56 +00002057 for (const auto *E : C->inits()) {
2058 Visitor->AddStmt(E);
2059 }
2060 for (const auto *E : C->updates()) {
2061 Visitor->AddStmt(E);
2062 }
2063 for (const auto *E : C->finals()) {
2064 Visitor->AddStmt(E);
2065 }
Alexander Musman8dba6642014-04-22 13:09:42 +00002066 Visitor->AddStmt(C->getStep());
Alexander Musman3276a272015-03-21 10:12:56 +00002067 Visitor->AddStmt(C->getCalcStep());
Alexander Musman8dba6642014-04-22 13:09:42 +00002068}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002069void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2070 VisitOMPClauseList(C);
2071 Visitor->AddStmt(C->getAlignment());
2072}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002073void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2074 VisitOMPClauseList(C);
Alexey Bataevf56f98c2015-04-16 05:39:01 +00002075 for (auto *E : C->source_exprs()) {
2076 Visitor->AddStmt(E);
2077 }
2078 for (auto *E : C->destination_exprs()) {
2079 Visitor->AddStmt(E);
2080 }
2081 for (auto *E : C->assignment_ops()) {
2082 Visitor->AddStmt(E);
2083 }
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002084}
Alexey Bataevbae9a792014-06-27 10:37:06 +00002085void
2086OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
2087 VisitOMPClauseList(C);
Alexey Bataeva63048e2015-03-23 06:18:07 +00002088 for (auto *E : C->source_exprs()) {
2089 Visitor->AddStmt(E);
2090 }
2091 for (auto *E : C->destination_exprs()) {
2092 Visitor->AddStmt(E);
2093 }
2094 for (auto *E : C->assignment_ops()) {
2095 Visitor->AddStmt(E);
2096 }
Alexey Bataevbae9a792014-06-27 10:37:06 +00002097}
Alexey Bataev6125da92014-07-21 11:26:11 +00002098void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2099 VisitOMPClauseList(C);
2100}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002101}
Alexey Bataev756c1962013-09-24 03:17:45 +00002102
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002103void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2104 unsigned size = WL.size();
2105 OMPClauseEnqueue Visitor(this);
2106 Visitor.Visit(S);
2107 if (size == WL.size())
2108 return;
2109 // Now reverse the entries we just added. This will match the DFS
2110 // ordering performed by the worklist.
2111 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2112 std::reverse(I, E);
2113}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002114void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002115 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2116}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002117void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002118 AddDecl(B->getBlockDecl());
2119}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002120void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002121 EnqueueChildren(E);
2122 AddTypeLoc(E->getTypeSourceInfo());
2123}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002124void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
2125 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00002126 E = S->body_rend(); I != E; ++I) {
2127 AddStmt(*I);
2128 }
2129}
2130void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002131VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002132 AddStmt(S->getSubStmt());
2133 AddDeclarationNameInfo(S);
2134 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2135 AddNestedNameSpecifierLoc(QualifierLoc);
2136}
2137
2138void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002139VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002140 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2141 AddDeclarationNameInfo(E);
2142 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2143 AddNestedNameSpecifierLoc(QualifierLoc);
2144 if (!E->isImplicitAccess())
2145 AddStmt(E->getBase());
2146}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002147void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002148 // Enqueue the initializer , if any.
2149 AddStmt(E->getInitializer());
2150 // Enqueue the array size, if any.
2151 AddStmt(E->getArraySize());
2152 // Enqueue the allocated type.
2153 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2154 // Enqueue the placement arguments.
2155 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2156 AddStmt(E->getPlacementArg(I-1));
2157}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002158void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002159 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2160 AddStmt(CE->getArg(I-1));
2161 AddStmt(CE->getCallee());
2162 AddStmt(CE->getArg(0));
2163}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002164void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2165 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002166 // Visit the name of the type being destroyed.
2167 AddTypeLoc(E->getDestroyedTypeInfo());
2168 // Visit the scope type that looks disturbingly like the nested-name-specifier
2169 // but isn't.
2170 AddTypeLoc(E->getScopeTypeInfo());
2171 // Visit the nested-name-specifier.
2172 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2173 AddNestedNameSpecifierLoc(QualifierLoc);
2174 // Visit base expression.
2175 AddStmt(E->getBase());
2176}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002177void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2178 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002179 AddTypeLoc(E->getTypeSourceInfo());
2180}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002181void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2182 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002183 EnqueueChildren(E);
2184 AddTypeLoc(E->getTypeSourceInfo());
2185}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002186void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002187 EnqueueChildren(E);
2188 if (E->isTypeOperand())
2189 AddTypeLoc(E->getTypeOperandSourceInfo());
2190}
2191
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002192void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2193 const CXXUnresolvedConstructExpr *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::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002198 EnqueueChildren(E);
2199 if (E->isTypeOperand())
2200 AddTypeLoc(E->getTypeOperandSourceInfo());
2201}
2202
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002203void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002204 EnqueueChildren(S);
2205 AddDecl(S->getExceptionDecl());
2206}
2207
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002208void EnqueueVisitor::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002209 AddStmt(S->getBody());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002210 AddStmt(S->getRangeInit());
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002211 AddDecl(S->getLoopVariable());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002212}
2213
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002214void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002215 if (DR->hasExplicitTemplateArgs()) {
2216 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2217 }
2218 WL.push_back(DeclRefExprParts(DR, Parent));
2219}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002220void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2221 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002222 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2223 AddDeclarationNameInfo(E);
2224 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2225}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002226void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002227 unsigned size = WL.size();
2228 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002229 for (const auto *D : S->decls()) {
2230 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002231 isFirst = false;
2232 }
2233 if (size == WL.size())
2234 return;
2235 // Now reverse the entries we just added. This will match the DFS
2236 // ordering performed by the worklist.
2237 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2238 std::reverse(I, E);
2239}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002240void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002241 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002242 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002243 D = E->designators_rbegin(), DEnd = E->designators_rend();
2244 D != DEnd; ++D) {
2245 if (D->isFieldDesignator()) {
2246 if (FieldDecl *Field = D->getField())
2247 AddMemberRef(Field, D->getFieldLoc());
2248 continue;
2249 }
2250 if (D->isArrayDesignator()) {
2251 AddStmt(E->getArrayIndex(*D));
2252 continue;
2253 }
2254 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2255 AddStmt(E->getArrayRangeEnd(*D));
2256 AddStmt(E->getArrayRangeStart(*D));
2257 }
2258}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002259void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002260 EnqueueChildren(E);
2261 AddTypeLoc(E->getTypeInfoAsWritten());
2262}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002263void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002264 AddStmt(FS->getBody());
2265 AddStmt(FS->getInc());
2266 AddStmt(FS->getCond());
2267 AddDecl(FS->getConditionVariable());
2268 AddStmt(FS->getInit());
2269}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002270void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002271 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2272}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002273void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002274 AddStmt(If->getElse());
2275 AddStmt(If->getThen());
2276 AddStmt(If->getCond());
2277 AddDecl(If->getConditionVariable());
2278}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002279void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002280 // We care about the syntactic form of the initializer list, only.
2281 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2282 IE = Syntactic;
2283 EnqueueChildren(IE);
2284}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002285void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002286 WL.push_back(MemberExprParts(M, Parent));
2287
2288 // If the base of the member access expression is an implicit 'this', don't
2289 // visit it.
2290 // FIXME: If we ever want to show these implicit accesses, this will be
2291 // unfortunate. However, clang_getCursor() relies on this behavior.
Argyrios Kyrtzidis58d0e7a2015-03-13 04:40:07 +00002292 if (M->isImplicitAccess())
2293 return;
2294
2295 // Ignore base anonymous struct/union fields, otherwise they will shadow the
2296 // real field that that we are interested in.
2297 if (auto *SubME = dyn_cast<MemberExpr>(M->getBase())) {
2298 if (auto *FD = dyn_cast_or_null<FieldDecl>(SubME->getMemberDecl())) {
2299 if (FD->isAnonymousStructOrUnion()) {
2300 AddStmt(SubME->getBase());
2301 return;
2302 }
2303 }
2304 }
2305
2306 AddStmt(M->getBase());
Guy Benyei11169dd2012-12-18 14:30:41 +00002307}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002308void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002309 AddTypeLoc(E->getEncodedTypeSourceInfo());
2310}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002311void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002312 EnqueueChildren(M);
2313 AddTypeLoc(M->getClassReceiverTypeInfo());
2314}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002315void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002316 // Visit the components of the offsetof expression.
2317 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2318 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2319 const OffsetOfNode &Node = E->getComponent(I-1);
2320 switch (Node.getKind()) {
2321 case OffsetOfNode::Array:
2322 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2323 break;
2324 case OffsetOfNode::Field:
2325 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2326 break;
2327 case OffsetOfNode::Identifier:
2328 case OffsetOfNode::Base:
2329 continue;
2330 }
2331 }
2332 // Visit the type into which we're computing the offset.
2333 AddTypeLoc(E->getTypeSourceInfo());
2334}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002335void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002336 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2337 WL.push_back(OverloadExprParts(E, Parent));
2338}
2339void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002340 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002341 EnqueueChildren(E);
2342 if (E->isArgumentType())
2343 AddTypeLoc(E->getArgumentTypeInfo());
2344}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002345void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002346 EnqueueChildren(S);
2347}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002348void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002349 AddStmt(S->getBody());
2350 AddStmt(S->getCond());
2351 AddDecl(S->getConditionVariable());
2352}
2353
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002354void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002355 AddStmt(W->getBody());
2356 AddStmt(W->getCond());
2357 AddDecl(W->getConditionVariable());
2358}
2359
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002360void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002361 for (unsigned I = E->getNumArgs(); I > 0; --I)
2362 AddTypeLoc(E->getArg(I-1));
2363}
2364
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002365void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002366 AddTypeLoc(E->getQueriedTypeSourceInfo());
2367}
2368
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002369void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002370 EnqueueChildren(E);
2371}
2372
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002373void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002374 VisitOverloadExpr(U);
2375 if (!U->isImplicitAccess())
2376 AddStmt(U->getBase());
2377}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002378void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002379 AddStmt(E->getSubExpr());
2380 AddTypeLoc(E->getWrittenTypeInfo());
2381}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002382void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002383 WL.push_back(SizeOfPackExprParts(E, Parent));
2384}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002385void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002386 // If the opaque value has a source expression, just transparently
2387 // visit that. This is useful for (e.g.) pseudo-object expressions.
2388 if (Expr *SourceExpr = E->getSourceExpr())
2389 return Visit(SourceExpr);
2390}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002391void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002392 AddStmt(E->getBody());
2393 WL.push_back(LambdaExprParts(E, Parent));
2394}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002395void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002396 // Treat the expression like its syntactic form.
2397 Visit(E->getSyntacticForm());
2398}
2399
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002400void EnqueueVisitor::VisitOMPExecutableDirective(
2401 const OMPExecutableDirective *D) {
2402 EnqueueChildren(D);
2403 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2404 E = D->clauses().end();
2405 I != E; ++I)
2406 EnqueueChildren(*I);
2407}
2408
Alexander Musman3aaab662014-08-19 11:27:13 +00002409void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
2410 VisitOMPExecutableDirective(D);
2411}
2412
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002413void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2414 VisitOMPExecutableDirective(D);
2415}
2416
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002417void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002418 VisitOMPLoopDirective(D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002419}
2420
Alexey Bataevf29276e2014-06-18 04:14:57 +00002421void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002422 VisitOMPLoopDirective(D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002423}
2424
Alexander Musmanf82886e2014-09-18 05:12:34 +00002425void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
2426 VisitOMPLoopDirective(D);
2427}
2428
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002429void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2430 VisitOMPExecutableDirective(D);
2431}
2432
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002433void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2434 VisitOMPExecutableDirective(D);
2435}
2436
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002437void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2438 VisitOMPExecutableDirective(D);
2439}
2440
Alexander Musman80c22892014-07-17 08:54:58 +00002441void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2442 VisitOMPExecutableDirective(D);
2443}
2444
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002445void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2446 VisitOMPExecutableDirective(D);
2447 AddDeclarationNameInfo(D);
2448}
2449
Alexey Bataev4acb8592014-07-07 13:01:15 +00002450void
2451EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002452 VisitOMPLoopDirective(D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002453}
2454
Alexander Musmane4e893b2014-09-23 09:33:00 +00002455void EnqueueVisitor::VisitOMPParallelForSimdDirective(
2456 const OMPParallelForSimdDirective *D) {
2457 VisitOMPLoopDirective(D);
2458}
2459
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002460void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2461 const OMPParallelSectionsDirective *D) {
2462 VisitOMPExecutableDirective(D);
2463}
2464
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002465void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2466 VisitOMPExecutableDirective(D);
2467}
2468
Alexey Bataev68446b72014-07-18 07:47:19 +00002469void
2470EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2471 VisitOMPExecutableDirective(D);
2472}
2473
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002474void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2475 VisitOMPExecutableDirective(D);
2476}
2477
Alexey Bataev2df347a2014-07-18 10:17:07 +00002478void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2479 VisitOMPExecutableDirective(D);
2480}
2481
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002482void EnqueueVisitor::VisitOMPTaskgroupDirective(
2483 const OMPTaskgroupDirective *D) {
2484 VisitOMPExecutableDirective(D);
2485}
2486
Alexey Bataev6125da92014-07-21 11:26:11 +00002487void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2488 VisitOMPExecutableDirective(D);
2489}
2490
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002491void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2492 VisitOMPExecutableDirective(D);
2493}
2494
Alexey Bataev0162e452014-07-22 10:10:35 +00002495void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2496 VisitOMPExecutableDirective(D);
2497}
2498
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002499void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
2500 VisitOMPExecutableDirective(D);
2501}
2502
Alexey Bataev13314bf2014-10-09 04:18:56 +00002503void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {
2504 VisitOMPExecutableDirective(D);
2505}
2506
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002507void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002508 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2509}
2510
2511bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2512 if (RegionOfInterest.isValid()) {
2513 SourceRange Range = getRawCursorExtent(C);
2514 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2515 return false;
2516 }
2517 return true;
2518}
2519
2520bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2521 while (!WL.empty()) {
2522 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002523 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002524
2525 // Set the Parent field, then back to its old value once we're done.
2526 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2527
2528 switch (LI.getKind()) {
2529 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002530 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002531 if (!D)
2532 continue;
2533
2534 // For now, perform default visitation for Decls.
2535 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2536 cast<DeclVisit>(&LI)->isFirst())))
2537 return true;
2538
2539 continue;
2540 }
2541 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2542 const ASTTemplateArgumentListInfo *ArgList =
2543 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2544 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2545 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2546 Arg != ArgEnd; ++Arg) {
2547 if (VisitTemplateArgumentLoc(*Arg))
2548 return true;
2549 }
2550 continue;
2551 }
2552 case VisitorJob::TypeLocVisitKind: {
2553 // Perform default visitation for TypeLocs.
2554 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2555 return true;
2556 continue;
2557 }
2558 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002559 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002560 if (LabelStmt *stmt = LS->getStmt()) {
2561 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2562 TU))) {
2563 return true;
2564 }
2565 }
2566 continue;
2567 }
2568
2569 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2570 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2571 if (VisitNestedNameSpecifierLoc(V->get()))
2572 return true;
2573 continue;
2574 }
2575
2576 case VisitorJob::DeclarationNameInfoVisitKind: {
2577 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2578 ->get()))
2579 return true;
2580 continue;
2581 }
2582 case VisitorJob::MemberRefVisitKind: {
2583 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2584 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2585 return true;
2586 continue;
2587 }
2588 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002589 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002590 if (!S)
2591 continue;
2592
2593 // Update the current cursor.
2594 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2595 if (!IsInRegionOfInterest(Cursor))
2596 continue;
2597 switch (Visitor(Cursor, Parent, ClientData)) {
2598 case CXChildVisit_Break: return true;
2599 case CXChildVisit_Continue: break;
2600 case CXChildVisit_Recurse:
2601 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002602 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002603 EnqueueWorkList(WL, S);
2604 break;
2605 }
2606 continue;
2607 }
2608 case VisitorJob::MemberExprPartsKind: {
2609 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002610 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002611
2612 // Visit the nested-name-specifier
2613 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2614 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2615 return true;
2616
2617 // Visit the declaration name.
2618 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2619 return true;
2620
2621 // Visit the explicitly-specified template arguments, if any.
2622 if (M->hasExplicitTemplateArgs()) {
2623 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2624 *ArgEnd = Arg + M->getNumTemplateArgs();
2625 Arg != ArgEnd; ++Arg) {
2626 if (VisitTemplateArgumentLoc(*Arg))
2627 return true;
2628 }
2629 }
2630 continue;
2631 }
2632 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002633 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002634 // Visit nested-name-specifier, if present.
2635 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2636 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2637 return true;
2638 // Visit declaration name.
2639 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2640 return true;
2641 continue;
2642 }
2643 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002644 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002645 // Visit the nested-name-specifier.
2646 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2647 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2648 return true;
2649 // Visit the declaration name.
2650 if (VisitDeclarationNameInfo(O->getNameInfo()))
2651 return true;
2652 // Visit the overloaded declaration reference.
2653 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2654 return true;
2655 continue;
2656 }
2657 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002658 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002659 NamedDecl *Pack = E->getPack();
2660 if (isa<TemplateTypeParmDecl>(Pack)) {
2661 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2662 E->getPackLoc(), TU)))
2663 return true;
2664
2665 continue;
2666 }
2667
2668 if (isa<TemplateTemplateParmDecl>(Pack)) {
2669 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2670 E->getPackLoc(), TU)))
2671 return true;
2672
2673 continue;
2674 }
2675
2676 // Non-type template parameter packs and function parameter packs are
2677 // treated like DeclRefExpr cursors.
2678 continue;
2679 }
2680
2681 case VisitorJob::LambdaExprPartsKind: {
2682 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002683 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002684 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2685 CEnd = E->explicit_capture_end();
2686 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002687 // FIXME: Lambda init-captures.
2688 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002689 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002690
Guy Benyei11169dd2012-12-18 14:30:41 +00002691 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2692 C->getLocation(),
2693 TU)))
2694 return true;
2695 }
2696
2697 // Visit parameters and return type, if present.
2698 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2699 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2700 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2701 // Visit the whole type.
2702 if (Visit(TL))
2703 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002704 } else if (FunctionProtoTypeLoc Proto =
2705 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002706 if (E->hasExplicitParameters()) {
2707 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002708 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2709 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002710 return true;
2711 } else {
2712 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002713 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002714 return true;
2715 }
2716 }
2717 }
2718 break;
2719 }
2720
2721 case VisitorJob::PostChildrenVisitKind:
2722 if (PostChildrenVisitor(Parent, ClientData))
2723 return true;
2724 break;
2725 }
2726 }
2727 return false;
2728}
2729
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002730bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002731 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002732 if (!WorkListFreeList.empty()) {
2733 WL = WorkListFreeList.back();
2734 WL->clear();
2735 WorkListFreeList.pop_back();
2736 }
2737 else {
2738 WL = new VisitorWorkList();
2739 WorkListCache.push_back(WL);
2740 }
2741 EnqueueWorkList(*WL, S);
2742 bool result = RunVisitorWorkList(*WL);
2743 WorkListFreeList.push_back(WL);
2744 return result;
2745}
2746
2747namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002748typedef SmallVector<SourceRange, 4> RefNamePieces;
Craig Topper69186e72014-06-08 08:38:04 +00002749RefNamePieces
2750buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2751 const DeclarationNameInfo &NI, const SourceRange &QLoc,
2752 const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002753 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2754 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2755 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2756
2757 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2758
2759 RefNamePieces Pieces;
2760
2761 if (WantQualifier && QLoc.isValid())
2762 Pieces.push_back(QLoc);
2763
2764 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2765 Pieces.push_back(NI.getLoc());
2766
2767 if (WantTemplateArgs && TemplateArgs)
2768 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2769 TemplateArgs->RAngleLoc));
2770
2771 if (Kind == DeclarationName::CXXOperatorName) {
2772 Pieces.push_back(SourceLocation::getFromRawEncoding(
2773 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2774 Pieces.push_back(SourceLocation::getFromRawEncoding(
2775 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2776 }
2777
2778 if (WantSinglePiece) {
2779 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2780 Pieces.clear();
2781 Pieces.push_back(R);
2782 }
2783
2784 return Pieces;
2785}
2786}
2787
2788//===----------------------------------------------------------------------===//
2789// Misc. API hooks.
2790//===----------------------------------------------------------------------===//
2791
Chad Rosier05c71aa2013-03-27 18:28:23 +00002792static void fatal_error_handler(void *user_data, const std::string& reason,
2793 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002794 // Write the result out to stderr avoiding errs() because raw_ostreams can
2795 // call report_fatal_error.
2796 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2797 ::abort();
2798}
2799
Chandler Carruth66660742014-06-27 16:37:27 +00002800namespace {
2801struct RegisterFatalErrorHandler {
2802 RegisterFatalErrorHandler() {
2803 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2804 }
2805};
2806}
2807
2808static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
2809
Guy Benyei11169dd2012-12-18 14:30:41 +00002810extern "C" {
2811CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2812 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002813 // We use crash recovery to make some of our APIs more reliable, implicitly
2814 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002815 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2816 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002817
Chandler Carruth66660742014-06-27 16:37:27 +00002818 // Look through the managed static to trigger construction of the managed
2819 // static which registers our fatal error handler. This ensures it is only
2820 // registered once.
2821 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00002822
2823 CIndexer *CIdxr = new CIndexer();
2824 if (excludeDeclarationsFromPCH)
2825 CIdxr->setOnlyLocalDecls();
2826 if (displayDiagnostics)
2827 CIdxr->setDisplayDiagnostics();
2828
2829 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2830 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2831 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2832 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2833 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2834 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2835
2836 return CIdxr;
2837}
2838
2839void clang_disposeIndex(CXIndex CIdx) {
2840 if (CIdx)
2841 delete static_cast<CIndexer *>(CIdx);
2842}
2843
2844void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2845 if (CIdx)
2846 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2847}
2848
2849unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2850 if (CIdx)
2851 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2852 return 0;
2853}
2854
2855void clang_toggleCrashRecovery(unsigned isEnabled) {
2856 if (isEnabled)
2857 llvm::CrashRecoveryContext::Enable();
2858 else
2859 llvm::CrashRecoveryContext::Disable();
2860}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002861
Guy Benyei11169dd2012-12-18 14:30:41 +00002862CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2863 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002864 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002865 enum CXErrorCode Result =
2866 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002867 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002868 assert((TU && Result == CXError_Success) ||
2869 (!TU && Result != CXError_Success));
2870 return TU;
2871}
2872
2873enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2874 const char *ast_filename,
2875 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002876 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002877 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002878
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002879 if (!CIdx || !ast_filename || !out_TU)
2880 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002881
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002882 LOG_FUNC_SECTION {
2883 *Log << ast_filename;
2884 }
2885
Guy Benyei11169dd2012-12-18 14:30:41 +00002886 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2887 FileSystemOptions FileSystemOpts;
2888
Justin Bognerd512c1e2014-10-15 00:33:06 +00002889 IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
2890 CompilerInstance::createDiagnostics(new DiagnosticOptions());
David Blaikie6f7382d2014-08-10 19:08:04 +00002891 std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
2892 ast_filename, Diags, FileSystemOpts, CXXIdx->getOnlyLocalDecls(), None,
2893 /*CaptureDiagnostics=*/true,
2894 /*AllowPCHWithCompilerErrors=*/true,
2895 /*UserFilesAreVolatile=*/true);
2896 *out_TU = MakeCXTranslationUnit(CXXIdx, AU.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002897 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002898}
2899
2900unsigned clang_defaultEditingTranslationUnitOptions() {
2901 return CXTranslationUnit_PrecompiledPreamble |
2902 CXTranslationUnit_CacheCompletionResults;
2903}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002904
Guy Benyei11169dd2012-12-18 14:30:41 +00002905CXTranslationUnit
2906clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2907 const char *source_filename,
2908 int num_command_line_args,
2909 const char * const *command_line_args,
2910 unsigned num_unsaved_files,
2911 struct CXUnsavedFile *unsaved_files) {
2912 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2913 return clang_parseTranslationUnit(CIdx, source_filename,
2914 command_line_args, num_command_line_args,
2915 unsaved_files, num_unsaved_files,
2916 Options);
2917}
2918
2919struct ParseTranslationUnitInfo {
2920 CXIndex CIdx;
2921 const char *source_filename;
2922 const char *const *command_line_args;
2923 int num_command_line_args;
Alp Toker9d85b182014-07-07 01:23:14 +00002924 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00002925 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002926 CXTranslationUnit *out_TU;
Alp Toker5c532982014-07-07 22:42:03 +00002927 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002928};
2929static void clang_parseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00002930 const ParseTranslationUnitInfo *PTUI =
2931 static_cast<ParseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00002932 CXIndex CIdx = PTUI->CIdx;
2933 const char *source_filename = PTUI->source_filename;
2934 const char * const *command_line_args = PTUI->command_line_args;
2935 int num_command_line_args = PTUI->num_command_line_args;
Guy Benyei11169dd2012-12-18 14:30:41 +00002936 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002937 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002938
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002939 // Set up the initial return values.
2940 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002941 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002942
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002943 // Check arguments.
Alp Toker9d85b182014-07-07 01:23:14 +00002944 if (!CIdx || !out_TU) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002945 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002946 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002947 }
2948
Guy Benyei11169dd2012-12-18 14:30:41 +00002949 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2950
2951 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2952 setThreadBackgroundPriority();
2953
2954 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2955 // FIXME: Add a flag for modules.
2956 TranslationUnitKind TUKind
2957 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002958 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002959 = options & CXTranslationUnit_CacheCompletionResults;
2960 bool IncludeBriefCommentsInCodeCompletion
2961 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2962 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2963 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2964
2965 // Configure the diagnostics.
2966 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002967 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002968
2969 // Recover resources if we crash before exiting this function.
2970 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2971 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00002972 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00002973
Ahmed Charlesb8984322014-03-07 20:03:18 +00002974 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
2975 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002976
2977 // Recover resources if we crash before exiting this function.
2978 llvm::CrashRecoveryContextCleanupRegistrar<
2979 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2980
Alp Toker9d85b182014-07-07 01:23:14 +00002981 for (auto &UF : PTUI->unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00002982 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00002983 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00002984 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00002985 }
2986
Ahmed Charlesb8984322014-03-07 20:03:18 +00002987 std::unique_ptr<std::vector<const char *>> Args(
2988 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002989
2990 // Recover resources if we crash before exiting this method.
2991 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2992 ArgsCleanup(Args.get());
2993
2994 // Since the Clang C library is primarily used by batch tools dealing with
2995 // (often very broken) source code, where spell-checking can have a
2996 // significant negative impact on performance (particularly when
2997 // precompiled headers are involved), we disable it by default.
2998 // Only do this if we haven't found a spell-checking-related argument.
2999 bool FoundSpellCheckingArgument = false;
3000 for (int I = 0; I != num_command_line_args; ++I) {
3001 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
3002 strcmp(command_line_args[I], "-fspell-checking") == 0) {
3003 FoundSpellCheckingArgument = true;
3004 break;
3005 }
3006 }
3007 if (!FoundSpellCheckingArgument)
3008 Args->push_back("-fno-spell-checking");
3009
3010 Args->insert(Args->end(), command_line_args,
3011 command_line_args + num_command_line_args);
3012
3013 // The 'source_filename' argument is optional. If the caller does not
3014 // specify it then it is assumed that the source file is specified
3015 // in the actual argument list.
3016 // Put the source file after command_line_args otherwise if '-x' flag is
3017 // present it will be unused.
3018 if (source_filename)
3019 Args->push_back(source_filename);
3020
3021 // Do we need the detailed preprocessing record?
3022 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
3023 Args->push_back("-Xclang");
3024 Args->push_back("-detailed-preprocessing-record");
3025 }
3026
3027 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00003028 std::unique_ptr<ASTUnit> ErrUnit;
3029 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Dmitri Gribenko340dd512014-03-12 15:35:53 +00003030 Args->data(), Args->data() + Args->size(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00003031 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
3032 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
3033 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
3034 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
3035 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
3036 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00003037
3038 if (NumErrors != Diags->getClient()->getNumErrors()) {
3039 // Make sure to check that 'Unit' is non-NULL.
3040 if (CXXIdx->getDisplayDiagnostics())
3041 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
3042 }
3043
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003044 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
3045 PTUI->result = CXError_ASTReadError;
3046 } else {
Ahmed Charles9a16beb2014-03-07 19:33:25 +00003047 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003048 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
3049 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003050}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003051
3052CXTranslationUnit
3053clang_parseTranslationUnit(CXIndex CIdx,
3054 const char *source_filename,
3055 const char *const *command_line_args,
3056 int num_command_line_args,
3057 struct CXUnsavedFile *unsaved_files,
3058 unsigned num_unsaved_files,
3059 unsigned options) {
3060 CXTranslationUnit TU;
3061 enum CXErrorCode Result = clang_parseTranslationUnit2(
3062 CIdx, source_filename, command_line_args, num_command_line_args,
3063 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00003064 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003065 assert((TU && Result == CXError_Success) ||
3066 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003067 return TU;
3068}
3069
3070enum CXErrorCode clang_parseTranslationUnit2(
3071 CXIndex CIdx,
3072 const char *source_filename,
3073 const char *const *command_line_args,
3074 int num_command_line_args,
3075 struct CXUnsavedFile *unsaved_files,
3076 unsigned num_unsaved_files,
3077 unsigned options,
3078 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003079 LOG_FUNC_SECTION {
3080 *Log << source_filename << ": ";
3081 for (int i = 0; i != num_command_line_args; ++i)
3082 *Log << command_line_args[i] << " ";
3083 }
3084
Alp Toker9d85b182014-07-07 01:23:14 +00003085 if (num_unsaved_files && !unsaved_files)
3086 return CXError_InvalidArguments;
3087
Alp Toker5c532982014-07-07 22:42:03 +00003088 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00003089 ParseTranslationUnitInfo PTUI = {
3090 CIdx,
3091 source_filename,
3092 command_line_args,
3093 num_command_line_args,
3094 llvm::makeArrayRef(unsaved_files, num_unsaved_files),
3095 options,
3096 out_TU,
Alp Toker5c532982014-07-07 22:42:03 +00003097 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00003098 llvm::CrashRecoveryContext CRC;
3099
3100 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
3101 fprintf(stderr, "libclang: crash detected during parsing: {\n");
3102 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3103 fprintf(stderr, " 'command_line_args' : [");
3104 for (int i = 0; i != num_command_line_args; ++i) {
3105 if (i)
3106 fprintf(stderr, ", ");
3107 fprintf(stderr, "'%s'", command_line_args[i]);
3108 }
3109 fprintf(stderr, "],\n");
3110 fprintf(stderr, " 'unsaved_files' : [");
3111 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3112 if (i)
3113 fprintf(stderr, ", ");
3114 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3115 unsaved_files[i].Length);
3116 }
3117 fprintf(stderr, "],\n");
3118 fprintf(stderr, " 'options' : %d,\n", options);
3119 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003120
3121 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003122 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003123 if (CXTranslationUnit *TU = PTUI.out_TU)
3124 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003125 }
Alp Toker5c532982014-07-07 22:42:03 +00003126
3127 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003128}
3129
3130unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
3131 return CXSaveTranslationUnit_None;
3132}
3133
3134namespace {
3135
3136struct SaveTranslationUnitInfo {
3137 CXTranslationUnit TU;
3138 const char *FileName;
3139 unsigned options;
3140 CXSaveError result;
3141};
3142
3143}
3144
3145static void clang_saveTranslationUnit_Impl(void *UserData) {
3146 SaveTranslationUnitInfo *STUI =
3147 static_cast<SaveTranslationUnitInfo*>(UserData);
3148
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003149 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003150 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3151 setThreadBackgroundPriority();
3152
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003153 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00003154 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
3155}
3156
3157int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3158 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003159 LOG_FUNC_SECTION {
3160 *Log << TU << ' ' << FileName;
3161 }
3162
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003163 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003164 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003165 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003166 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003167
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003168 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003169 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3170 if (!CXXUnit->hasSema())
3171 return CXSaveError_InvalidTU;
3172
3173 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
3174
3175 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3176 getenv("LIBCLANG_NOTHREADS")) {
3177 clang_saveTranslationUnit_Impl(&STUI);
3178
3179 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3180 PrintLibclangResourceUsage(TU);
3181
3182 return STUI.result;
3183 }
3184
3185 // We have an AST that has invalid nodes due to compiler errors.
3186 // Use a crash recovery thread for protection.
3187
3188 llvm::CrashRecoveryContext CRC;
3189
3190 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
3191 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3192 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3193 fprintf(stderr, " 'options' : %d,\n", options);
3194 fprintf(stderr, "}\n");
3195
3196 return CXSaveError_Unknown;
3197
3198 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3199 PrintLibclangResourceUsage(TU);
3200 }
3201
3202 return STUI.result;
3203}
3204
3205void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3206 if (CTUnit) {
3207 // If the translation unit has been marked as unsafe to free, just discard
3208 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003209 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3210 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003211 return;
3212
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003213 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003214 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003215 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3216 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003217 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003218 delete CTUnit;
3219 }
3220}
3221
3222unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3223 return CXReparse_None;
3224}
3225
3226struct ReparseTranslationUnitInfo {
3227 CXTranslationUnit TU;
Alp Toker9d85b182014-07-07 01:23:14 +00003228 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00003229 unsigned options;
Alp Toker5c532982014-07-07 22:42:03 +00003230 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003231};
3232
3233static void clang_reparseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00003234 const ReparseTranslationUnitInfo *RTUI =
3235 static_cast<ReparseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00003236 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003237 unsigned options = RTUI->options;
3238 (void) options;
3239
3240 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003241 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003242 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003243 RTUI->result = CXError_InvalidArguments;
3244 return;
3245 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003246
3247 // Reset the associated diagnostics.
3248 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003249 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003250
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003251 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003252 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3253 setThreadBackgroundPriority();
3254
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003255 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003256 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003257
3258 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3259 new std::vector<ASTUnit::RemappedFile>());
3260
Guy Benyei11169dd2012-12-18 14:30:41 +00003261 // Recover resources if we crash before exiting this function.
3262 llvm::CrashRecoveryContextCleanupRegistrar<
3263 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003264
3265 for (auto &UF : RTUI->unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003266 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003267 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003268 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003269 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003270
Dmitri Gribenko2febd212014-02-07 15:00:22 +00003271 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003272 RTUI->result = CXError_Success;
3273 else if (isASTReadError(CXXUnit))
3274 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003275}
3276
3277int clang_reparseTranslationUnit(CXTranslationUnit TU,
3278 unsigned num_unsaved_files,
3279 struct CXUnsavedFile *unsaved_files,
3280 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003281 LOG_FUNC_SECTION {
3282 *Log << TU;
3283 }
3284
Alp Toker9d85b182014-07-07 01:23:14 +00003285 if (num_unsaved_files && !unsaved_files)
3286 return CXError_InvalidArguments;
3287
Alp Toker5c532982014-07-07 22:42:03 +00003288 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00003289 ReparseTranslationUnitInfo RTUI = {
3290 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options,
Alp Toker5c532982014-07-07 22:42:03 +00003291 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00003292
3293 if (getenv("LIBCLANG_NOTHREADS")) {
3294 clang_reparseTranslationUnit_Impl(&RTUI);
Alp Toker5c532982014-07-07 22:42:03 +00003295 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003296 }
3297
3298 llvm::CrashRecoveryContext CRC;
3299
3300 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3301 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003302 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003303 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003304 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3305 PrintLibclangResourceUsage(TU);
3306
Alp Toker5c532982014-07-07 22:42:03 +00003307 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003308}
3309
3310
3311CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003312 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003313 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003314 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003315 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003316
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003317 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003318 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003319}
3320
3321CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003322 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003323 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003324 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003325 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003326
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003327 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003328 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3329}
3330
3331} // end: extern "C"
3332
3333//===----------------------------------------------------------------------===//
3334// CXFile Operations.
3335//===----------------------------------------------------------------------===//
3336
3337extern "C" {
3338CXString clang_getFileName(CXFile SFile) {
3339 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003340 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003341
3342 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003343 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003344}
3345
3346time_t clang_getFileTime(CXFile SFile) {
3347 if (!SFile)
3348 return 0;
3349
3350 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3351 return FEnt->getModificationTime();
3352}
3353
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003354CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003355 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003356 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003357 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003358 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003359
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003360 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003361
3362 FileManager &FMgr = CXXUnit->getFileManager();
3363 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3364}
3365
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003366unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3367 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003368 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003369 LOG_BAD_TU(TU);
3370 return 0;
3371 }
3372
3373 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003374 return 0;
3375
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003376 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003377 FileEntry *FEnt = static_cast<FileEntry *>(file);
3378 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3379 .isFileMultipleIncludeGuarded(FEnt);
3380}
3381
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003382int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3383 if (!file || !outID)
3384 return 1;
3385
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003386 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003387 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3388 outID->data[0] = ID.getDevice();
3389 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003390 outID->data[2] = FEnt->getModificationTime();
3391 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003392}
3393
Argyrios Kyrtzidisac3997e2014-08-16 00:26:19 +00003394int clang_File_isEqual(CXFile file1, CXFile file2) {
3395 if (file1 == file2)
3396 return true;
3397
3398 if (!file1 || !file2)
3399 return false;
3400
3401 FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
3402 FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
3403 return FEnt1->getUniqueID() == FEnt2->getUniqueID();
3404}
3405
Guy Benyei11169dd2012-12-18 14:30:41 +00003406} // end: extern "C"
3407
3408//===----------------------------------------------------------------------===//
3409// CXCursor Operations.
3410//===----------------------------------------------------------------------===//
3411
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003412static const Decl *getDeclFromExpr(const Stmt *E) {
3413 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003414 return getDeclFromExpr(CE->getSubExpr());
3415
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003416 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003417 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003418 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003419 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003420 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003421 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003422 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003423 if (PRE->isExplicitProperty())
3424 return PRE->getExplicitProperty();
3425 // It could be messaging both getter and setter as in:
3426 // ++myobj.myprop;
3427 // in which case prefer to associate the setter since it is less obvious
3428 // from inspecting the source that the setter is going to get called.
3429 if (PRE->isMessagingSetter())
3430 return PRE->getImplicitPropertySetter();
3431 return PRE->getImplicitPropertyGetter();
3432 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003433 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003434 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003435 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003436 if (Expr *Src = OVE->getSourceExpr())
3437 return getDeclFromExpr(Src);
3438
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003439 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003440 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003441 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003442 if (!CE->isElidable())
3443 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003444 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003445 return OME->getMethodDecl();
3446
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003447 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003448 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003449 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003450 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3451 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003452 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003453 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3454 isa<ParmVarDecl>(SizeOfPack->getPack()))
3455 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003456
3457 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003458}
3459
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003460static SourceLocation getLocationFromExpr(const Expr *E) {
3461 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003462 return getLocationFromExpr(CE->getSubExpr());
3463
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003464 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003465 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003466 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003467 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003468 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003469 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003470 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003471 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003472 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003473 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003474 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003475 return PropRef->getLocation();
3476
3477 return E->getLocStart();
3478}
3479
3480extern "C" {
3481
3482unsigned clang_visitChildren(CXCursor parent,
3483 CXCursorVisitor visitor,
3484 CXClientData client_data) {
3485 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3486 /*VisitPreprocessorLast=*/false);
3487 return CursorVis.VisitChildren(parent);
3488}
3489
3490#ifndef __has_feature
3491#define __has_feature(x) 0
3492#endif
3493#if __has_feature(blocks)
3494typedef enum CXChildVisitResult
3495 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3496
3497static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3498 CXClientData client_data) {
3499 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3500 return block(cursor, parent);
3501}
3502#else
3503// If we are compiled with a compiler that doesn't have native blocks support,
3504// define and call the block manually, so the
3505typedef struct _CXChildVisitResult
3506{
3507 void *isa;
3508 int flags;
3509 int reserved;
3510 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3511 CXCursor);
3512} *CXCursorVisitorBlock;
3513
3514static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3515 CXClientData client_data) {
3516 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3517 return block->invoke(block, cursor, parent);
3518}
3519#endif
3520
3521
3522unsigned clang_visitChildrenWithBlock(CXCursor parent,
3523 CXCursorVisitorBlock block) {
3524 return clang_visitChildren(parent, visitWithBlock, block);
3525}
3526
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003527static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003528 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003529 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003530
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003531 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003532 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003533 if (const ObjCPropertyImplDecl *PropImpl =
3534 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003535 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003536 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003537
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003538 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003539 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003540 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003541
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003542 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003543 }
3544
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003545 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003546 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003547
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003548 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003549 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3550 // and returns different names. NamedDecl returns the class name and
3551 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003552 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003553
3554 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003555 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003556
3557 SmallString<1024> S;
3558 llvm::raw_svector_ostream os(S);
3559 ND->printName(os);
3560
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003561 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003562}
3563
3564CXString clang_getCursorSpelling(CXCursor C) {
3565 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003566 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003567
3568 if (clang_isReference(C.kind)) {
3569 switch (C.kind) {
3570 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003571 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003572 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003573 }
3574 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003575 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003576 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003577 }
3578 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003579 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003580 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003581 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003582 }
3583 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003584 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003585 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003586 }
3587 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003588 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003589 assert(Type && "Missing type decl");
3590
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003591 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003592 getAsString());
3593 }
3594 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003595 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003596 assert(Template && "Missing template decl");
3597
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003598 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003599 }
3600
3601 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003602 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003603 assert(NS && "Missing namespace decl");
3604
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003605 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003606 }
3607
3608 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003609 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003610 assert(Field && "Missing member decl");
3611
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003612 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003613 }
3614
3615 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003616 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003617 assert(Label && "Missing label");
3618
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003619 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003620 }
3621
3622 case CXCursor_OverloadedDeclRef: {
3623 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003624 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3625 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003626 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003627 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003628 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003629 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003630 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003631 OverloadedTemplateStorage *Ovl
3632 = Storage.get<OverloadedTemplateStorage*>();
3633 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003634 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003635 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003636 }
3637
3638 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003639 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003640 assert(Var && "Missing variable decl");
3641
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003642 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003643 }
3644
3645 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003646 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003647 }
3648 }
3649
3650 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003651 const Expr *E = getCursorExpr(C);
3652
3653 if (C.kind == CXCursor_ObjCStringLiteral ||
3654 C.kind == CXCursor_StringLiteral) {
3655 const StringLiteral *SLit;
3656 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3657 SLit = OSL->getString();
3658 } else {
3659 SLit = cast<StringLiteral>(E);
3660 }
3661 SmallString<256> Buf;
3662 llvm::raw_svector_ostream OS(Buf);
3663 SLit->outputString(OS);
3664 return cxstring::createDup(OS.str());
3665 }
3666
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003667 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003668 if (D)
3669 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003670 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003671 }
3672
3673 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003674 const Stmt *S = getCursorStmt(C);
3675 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003676 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003677
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003678 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003679 }
3680
3681 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003682 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003683 ->getNameStart());
3684
3685 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003686 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003687 ->getNameStart());
3688
3689 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003690 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003691
3692 if (clang_isDeclaration(C.kind))
3693 return getDeclSpelling(getCursorDecl(C));
3694
3695 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003696 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003697 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003698 }
3699
3700 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003701 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003702 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003703 }
3704
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003705 if (C.kind == CXCursor_PackedAttr) {
3706 return cxstring::createRef("packed");
3707 }
3708
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003709 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003710}
3711
3712CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3713 unsigned pieceIndex,
3714 unsigned options) {
3715 if (clang_Cursor_isNull(C))
3716 return clang_getNullRange();
3717
3718 ASTContext &Ctx = getCursorContext(C);
3719
3720 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003721 const Stmt *S = getCursorStmt(C);
3722 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003723 if (pieceIndex > 0)
3724 return clang_getNullRange();
3725 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3726 }
3727
3728 return clang_getNullRange();
3729 }
3730
3731 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003732 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003733 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3734 if (pieceIndex >= ME->getNumSelectorLocs())
3735 return clang_getNullRange();
3736 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3737 }
3738 }
3739
3740 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3741 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003742 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003743 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3744 if (pieceIndex >= MD->getNumSelectorLocs())
3745 return clang_getNullRange();
3746 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3747 }
3748 }
3749
3750 if (C.kind == CXCursor_ObjCCategoryDecl ||
3751 C.kind == CXCursor_ObjCCategoryImplDecl) {
3752 if (pieceIndex > 0)
3753 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003754 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003755 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3756 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003757 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003758 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3759 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3760 }
3761
3762 if (C.kind == CXCursor_ModuleImportDecl) {
3763 if (pieceIndex > 0)
3764 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003765 if (const ImportDecl *ImportD =
3766 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003767 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3768 if (!Locs.empty())
3769 return cxloc::translateSourceRange(Ctx,
3770 SourceRange(Locs.front(), Locs.back()));
3771 }
3772 return clang_getNullRange();
3773 }
3774
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00003775 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
3776 C.kind == CXCursor_ConversionFunction) {
3777 if (pieceIndex > 0)
3778 return clang_getNullRange();
3779 if (const FunctionDecl *FD =
3780 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
3781 DeclarationNameInfo FunctionName = FD->getNameInfo();
3782 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
3783 }
3784 return clang_getNullRange();
3785 }
3786
Guy Benyei11169dd2012-12-18 14:30:41 +00003787 // FIXME: A CXCursor_InclusionDirective should give the location of the
3788 // filename, but we don't keep track of this.
3789
3790 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3791 // but we don't keep track of this.
3792
3793 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3794 // but we don't keep track of this.
3795
3796 // Default handling, give the location of the cursor.
3797
3798 if (pieceIndex > 0)
3799 return clang_getNullRange();
3800
3801 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3802 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3803 return cxloc::translateSourceRange(Ctx, Loc);
3804}
3805
Eli Bendersky44a206f2014-07-31 18:04:56 +00003806CXString clang_Cursor_getMangling(CXCursor C) {
3807 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
3808 return cxstring::createEmpty();
3809
Eli Bendersky44a206f2014-07-31 18:04:56 +00003810 // Mangling only works for functions and variables.
Eli Bendersky79759592014-08-01 15:01:10 +00003811 const Decl *D = getCursorDecl(C);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003812 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
3813 return cxstring::createEmpty();
3814
Eli Bendersky79759592014-08-01 15:01:10 +00003815 // First apply frontend mangling.
Eli Bendersky44a206f2014-07-31 18:04:56 +00003816 const NamedDecl *ND = cast<NamedDecl>(D);
Eli Bendersky79759592014-08-01 15:01:10 +00003817 ASTContext &Ctx = ND->getASTContext();
3818 std::unique_ptr<MangleContext> MC(Ctx.createMangleContext());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003819
Eli Bendersky79759592014-08-01 15:01:10 +00003820 std::string FrontendBuf;
3821 llvm::raw_string_ostream FrontendBufOS(FrontendBuf);
3822 MC->mangleName(ND, FrontendBufOS);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003823
Eli Bendersky79759592014-08-01 15:01:10 +00003824 // Now apply backend mangling.
3825 std::unique_ptr<llvm::DataLayout> DL(
3826 new llvm::DataLayout(Ctx.getTargetInfo().getTargetDescription()));
3827 llvm::Mangler BackendMangler(DL.get());
3828
3829 std::string FinalBuf;
3830 llvm::raw_string_ostream FinalBufOS(FinalBuf);
3831 BackendMangler.getNameWithPrefix(FinalBufOS,
3832 llvm::Twine(FrontendBufOS.str()));
3833
3834 return cxstring::createDup(FinalBufOS.str());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003835}
3836
Guy Benyei11169dd2012-12-18 14:30:41 +00003837CXString clang_getCursorDisplayName(CXCursor C) {
3838 if (!clang_isDeclaration(C.kind))
3839 return clang_getCursorSpelling(C);
3840
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003841 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003842 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003843 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003844
3845 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003846 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003847 D = FunTmpl->getTemplatedDecl();
3848
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003849 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003850 SmallString<64> Str;
3851 llvm::raw_svector_ostream OS(Str);
3852 OS << *Function;
3853 if (Function->getPrimaryTemplate())
3854 OS << "<>";
3855 OS << "(";
3856 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3857 if (I)
3858 OS << ", ";
3859 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3860 }
3861
3862 if (Function->isVariadic()) {
3863 if (Function->getNumParams())
3864 OS << ", ";
3865 OS << "...";
3866 }
3867 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003868 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003869 }
3870
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003871 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003872 SmallString<64> Str;
3873 llvm::raw_svector_ostream OS(Str);
3874 OS << *ClassTemplate;
3875 OS << "<";
3876 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3877 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3878 if (I)
3879 OS << ", ";
3880
3881 NamedDecl *Param = Params->getParam(I);
3882 if (Param->getIdentifier()) {
3883 OS << Param->getIdentifier()->getName();
3884 continue;
3885 }
3886
3887 // There is no parameter name, which makes this tricky. Try to come up
3888 // with something useful that isn't too long.
3889 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3890 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3891 else if (NonTypeTemplateParmDecl *NTTP
3892 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3893 OS << NTTP->getType().getAsString(Policy);
3894 else
3895 OS << "template<...> class";
3896 }
3897
3898 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003899 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003900 }
3901
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003902 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003903 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3904 // If the type was explicitly written, use that.
3905 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003906 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003907
Benjamin Kramer9170e912013-02-22 15:46:01 +00003908 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003909 llvm::raw_svector_ostream OS(Str);
3910 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003911 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003912 ClassSpec->getTemplateArgs().data(),
3913 ClassSpec->getTemplateArgs().size(),
3914 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003915 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003916 }
3917
3918 return clang_getCursorSpelling(C);
3919}
3920
3921CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3922 switch (Kind) {
3923 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003924 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003925 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003926 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003927 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003928 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003929 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003930 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003931 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003932 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003933 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003934 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003935 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003936 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003937 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003938 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003939 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003940 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003941 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003942 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003943 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003944 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003945 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003946 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003947 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003948 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003949 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003950 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003951 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003952 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003953 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003954 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003955 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003956 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003957 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003958 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003959 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003960 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003961 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003962 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003963 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003964 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003965 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003966 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003967 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003968 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003969 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003970 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003971 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003972 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003973 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003974 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003975 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003976 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003977 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003978 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003979 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003980 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003981 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003982 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003983 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003984 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003985 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003986 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003987 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003988 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003989 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003990 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003991 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003992 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003993 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003994 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003995 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003996 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003997 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003998 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003999 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004000 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004001 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004002 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004003 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004004 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004005 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004006 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004007 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004008 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004009 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004010 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004011 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004012 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004013 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004014 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004015 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004016 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004017 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004018 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004019 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004020 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004021 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004022 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004023 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004024 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004025 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004026 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004027 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004028 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004029 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004030 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004031 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004032 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004033 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004034 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004035 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004036 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004037 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004038 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004039 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004040 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004041 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004042 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004043 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004044 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004045 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004046 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004047 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004048 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004049 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004050 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00004051 case CXCursor_ObjCSelfExpr:
4052 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004053 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004054 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004055 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004056 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004057 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004058 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004059 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004060 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004061 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004062 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004063 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004064 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004065 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004066 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004067 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004068 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004069 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004070 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004071 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004072 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004073 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004074 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004075 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004076 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004077 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004078 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004079 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004080 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004081 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004082 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004083 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004084 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004085 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004086 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004087 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004088 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004089 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004090 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004091 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004092 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004093 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004094 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004095 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004096 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004097 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004098 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004099 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004100 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004101 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004102 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004103 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004104 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004105 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004106 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004107 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004108 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004109 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004110 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004111 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004112 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004113 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004114 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004115 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004116 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004117 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004118 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004119 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004120 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004121 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004122 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004123 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004124 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004125 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004126 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004127 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004128 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004129 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004130 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004131 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004132 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004133 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004134 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004135 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004136 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004137 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004138 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004139 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004140 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00004141 case CXCursor_SEHLeaveStmt:
4142 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004143 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004144 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004145 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004146 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00004147 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004148 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00004149 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004150 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00004151 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004152 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00004153 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004154 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00004155 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004156 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004157 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004158 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004159 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004160 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004161 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004162 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004163 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004164 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004165 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004166 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004167 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004168 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004169 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004170 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004171 case CXCursor_PackedAttr:
4172 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00004173 case CXCursor_PureAttr:
4174 return cxstring::createRef("attribute(pure)");
4175 case CXCursor_ConstAttr:
4176 return cxstring::createRef("attribute(const)");
4177 case CXCursor_NoDuplicateAttr:
4178 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00004179 case CXCursor_CUDAConstantAttr:
4180 return cxstring::createRef("attribute(constant)");
4181 case CXCursor_CUDADeviceAttr:
4182 return cxstring::createRef("attribute(device)");
4183 case CXCursor_CUDAGlobalAttr:
4184 return cxstring::createRef("attribute(global)");
4185 case CXCursor_CUDAHostAttr:
4186 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00004187 case CXCursor_CUDASharedAttr:
4188 return cxstring::createRef("attribute(shared)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004189 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004190 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004191 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004192 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00004193 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004194 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004195 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004196 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004197 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004198 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00004199 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004200 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00004201 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004202 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004203 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004204 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004205 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004206 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004207 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004208 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004209 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004210 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004211 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004212 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004213 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004214 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004215 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004216 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004217 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004218 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004219 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004220 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004221 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004222 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004223 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004224 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004225 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004226 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004227 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004228 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004229 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004230 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004231 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004232 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004233 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004234 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004235 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004236 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004237 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004238 return cxstring::createRef("OMPParallelDirective");
4239 case CXCursor_OMPSimdDirective:
4240 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004241 case CXCursor_OMPForDirective:
4242 return cxstring::createRef("OMPForDirective");
Alexander Musmanf82886e2014-09-18 05:12:34 +00004243 case CXCursor_OMPForSimdDirective:
4244 return cxstring::createRef("OMPForSimdDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004245 case CXCursor_OMPSectionsDirective:
4246 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004247 case CXCursor_OMPSectionDirective:
4248 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004249 case CXCursor_OMPSingleDirective:
4250 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004251 case CXCursor_OMPMasterDirective:
4252 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004253 case CXCursor_OMPCriticalDirective:
4254 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004255 case CXCursor_OMPParallelForDirective:
4256 return cxstring::createRef("OMPParallelForDirective");
Alexander Musmane4e893b2014-09-23 09:33:00 +00004257 case CXCursor_OMPParallelForSimdDirective:
4258 return cxstring::createRef("OMPParallelForSimdDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004259 case CXCursor_OMPParallelSectionsDirective:
4260 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004261 case CXCursor_OMPTaskDirective:
4262 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004263 case CXCursor_OMPTaskyieldDirective:
4264 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004265 case CXCursor_OMPBarrierDirective:
4266 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004267 case CXCursor_OMPTaskwaitDirective:
4268 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00004269 case CXCursor_OMPTaskgroupDirective:
4270 return cxstring::createRef("OMPTaskgroupDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00004271 case CXCursor_OMPFlushDirective:
4272 return cxstring::createRef("OMPFlushDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004273 case CXCursor_OMPOrderedDirective:
4274 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00004275 case CXCursor_OMPAtomicDirective:
4276 return cxstring::createRef("OMPAtomicDirective");
Alexey Bataev0bd520b2014-09-19 08:19:49 +00004277 case CXCursor_OMPTargetDirective:
4278 return cxstring::createRef("OMPTargetDirective");
Alexey Bataev13314bf2014-10-09 04:18:56 +00004279 case CXCursor_OMPTeamsDirective:
4280 return cxstring::createRef("OMPTeamsDirective");
Francisco Lopes da Silva975a9f62015-01-21 16:24:11 +00004281 case CXCursor_OverloadCandidate:
4282 return cxstring::createRef("OverloadCandidate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004283 }
4284
4285 llvm_unreachable("Unhandled CXCursorKind");
4286}
4287
4288struct GetCursorData {
4289 SourceLocation TokenBeginLoc;
4290 bool PointsAtMacroArgExpansion;
4291 bool VisitedObjCPropertyImplDecl;
4292 SourceLocation VisitedDeclaratorDeclStartLoc;
4293 CXCursor &BestCursor;
4294
4295 GetCursorData(SourceManager &SM,
4296 SourceLocation tokenBegin, CXCursor &outputCursor)
4297 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4298 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4299 VisitedObjCPropertyImplDecl = false;
4300 }
4301};
4302
4303static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4304 CXCursor parent,
4305 CXClientData client_data) {
4306 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4307 CXCursor *BestCursor = &Data->BestCursor;
4308
4309 // If we point inside a macro argument we should provide info of what the
4310 // token is so use the actual cursor, don't replace it with a macro expansion
4311 // cursor.
4312 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4313 return CXChildVisit_Recurse;
4314
4315 if (clang_isDeclaration(cursor.kind)) {
4316 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004317 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004318 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4319 if (MD->isImplicit())
4320 return CXChildVisit_Break;
4321
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004322 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004323 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4324 // Check that when we have multiple @class references in the same line,
4325 // that later ones do not override the previous ones.
4326 // If we have:
4327 // @class Foo, Bar;
4328 // source ranges for both start at '@', so 'Bar' will end up overriding
4329 // 'Foo' even though the cursor location was at 'Foo'.
4330 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4331 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004332 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004333 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4334 if (PrevID != ID &&
4335 !PrevID->isThisDeclarationADefinition() &&
4336 !ID->isThisDeclarationADefinition())
4337 return CXChildVisit_Break;
4338 }
4339
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004340 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004341 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4342 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4343 // Check that when we have multiple declarators in the same line,
4344 // that later ones do not override the previous ones.
4345 // If we have:
4346 // int Foo, Bar;
4347 // source ranges for both start at 'int', so 'Bar' will end up overriding
4348 // 'Foo' even though the cursor location was at 'Foo'.
4349 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4350 return CXChildVisit_Break;
4351 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4352
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004353 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004354 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4355 (void)PropImp;
4356 // Check that when we have multiple @synthesize in the same line,
4357 // that later ones do not override the previous ones.
4358 // If we have:
4359 // @synthesize Foo, Bar;
4360 // source ranges for both start at '@', so 'Bar' will end up overriding
4361 // 'Foo' even though the cursor location was at 'Foo'.
4362 if (Data->VisitedObjCPropertyImplDecl)
4363 return CXChildVisit_Break;
4364 Data->VisitedObjCPropertyImplDecl = true;
4365 }
4366 }
4367
4368 if (clang_isExpression(cursor.kind) &&
4369 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004370 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004371 // Avoid having the cursor of an expression replace the declaration cursor
4372 // when the expression source range overlaps the declaration range.
4373 // This can happen for C++ constructor expressions whose range generally
4374 // include the variable declaration, e.g.:
4375 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4376 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4377 D->getLocation() == Data->TokenBeginLoc)
4378 return CXChildVisit_Break;
4379 }
4380 }
4381
4382 // If our current best cursor is the construction of a temporary object,
4383 // don't replace that cursor with a type reference, because we want
4384 // clang_getCursor() to point at the constructor.
4385 if (clang_isExpression(BestCursor->kind) &&
4386 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4387 cursor.kind == CXCursor_TypeRef) {
4388 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4389 // as having the actual point on the type reference.
4390 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4391 return CXChildVisit_Recurse;
4392 }
4393
4394 *BestCursor = cursor;
4395 return CXChildVisit_Recurse;
4396}
4397
4398CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004399 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004400 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004401 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004402 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004403
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004404 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004405 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4406
4407 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4408 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4409
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004410 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004411 CXFile SearchFile;
4412 unsigned SearchLine, SearchColumn;
4413 CXFile ResultFile;
4414 unsigned ResultLine, ResultColumn;
4415 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4416 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4417 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004418
4419 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4420 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004421 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004422 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004423 SearchFileName = clang_getFileName(SearchFile);
4424 ResultFileName = clang_getFileName(ResultFile);
4425 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4426 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004427 *Log << llvm::format("(%s:%d:%d) = %s",
4428 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4429 clang_getCString(KindSpelling))
4430 << llvm::format("(%s:%d:%d):%s%s",
4431 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4432 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004433 clang_disposeString(SearchFileName);
4434 clang_disposeString(ResultFileName);
4435 clang_disposeString(KindSpelling);
4436 clang_disposeString(USR);
4437
4438 CXCursor Definition = clang_getCursorDefinition(Result);
4439 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4440 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4441 CXString DefinitionKindSpelling
4442 = clang_getCursorKindSpelling(Definition.kind);
4443 CXFile DefinitionFile;
4444 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004445 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004446 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004447 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004448 *Log << llvm::format(" -> %s(%s:%d:%d)",
4449 clang_getCString(DefinitionKindSpelling),
4450 clang_getCString(DefinitionFileName),
4451 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004452 clang_disposeString(DefinitionFileName);
4453 clang_disposeString(DefinitionKindSpelling);
4454 }
4455 }
4456
4457 return Result;
4458}
4459
4460CXCursor clang_getNullCursor(void) {
4461 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4462}
4463
4464unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004465 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4466 // can't set consistently. For example, when visiting a DeclStmt we will set
4467 // it but we don't set it on the result of clang_getCursorDefinition for
4468 // a reference of the same declaration.
4469 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4470 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4471 // to provide that kind of info.
4472 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004473 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004474 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004475 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004476
Guy Benyei11169dd2012-12-18 14:30:41 +00004477 return X == Y;
4478}
4479
4480unsigned clang_hashCursor(CXCursor C) {
4481 unsigned Index = 0;
4482 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4483 Index = 1;
4484
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004485 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004486 std::make_pair(C.kind, C.data[Index]));
4487}
4488
4489unsigned clang_isInvalid(enum CXCursorKind K) {
4490 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4491}
4492
4493unsigned clang_isDeclaration(enum CXCursorKind K) {
4494 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4495 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4496}
4497
4498unsigned clang_isReference(enum CXCursorKind K) {
4499 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4500}
4501
4502unsigned clang_isExpression(enum CXCursorKind K) {
4503 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4504}
4505
4506unsigned clang_isStatement(enum CXCursorKind K) {
4507 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4508}
4509
4510unsigned clang_isAttribute(enum CXCursorKind K) {
4511 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4512}
4513
4514unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4515 return K == CXCursor_TranslationUnit;
4516}
4517
4518unsigned clang_isPreprocessing(enum CXCursorKind K) {
4519 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4520}
4521
4522unsigned clang_isUnexposed(enum CXCursorKind K) {
4523 switch (K) {
4524 case CXCursor_UnexposedDecl:
4525 case CXCursor_UnexposedExpr:
4526 case CXCursor_UnexposedStmt:
4527 case CXCursor_UnexposedAttr:
4528 return true;
4529 default:
4530 return false;
4531 }
4532}
4533
4534CXCursorKind clang_getCursorKind(CXCursor C) {
4535 return C.kind;
4536}
4537
4538CXSourceLocation clang_getCursorLocation(CXCursor C) {
4539 if (clang_isReference(C.kind)) {
4540 switch (C.kind) {
4541 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004542 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004543 = getCursorObjCSuperClassRef(C);
4544 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4545 }
4546
4547 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004548 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004549 = getCursorObjCProtocolRef(C);
4550 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4551 }
4552
4553 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004554 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004555 = getCursorObjCClassRef(C);
4556 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4557 }
4558
4559 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004560 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004561 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4562 }
4563
4564 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004565 std::pair<const TemplateDecl *, SourceLocation> P =
4566 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004567 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4568 }
4569
4570 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004571 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004572 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4573 }
4574
4575 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004576 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004577 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4578 }
4579
4580 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004581 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004582 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4583 }
4584
4585 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004586 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004587 if (!BaseSpec)
4588 return clang_getNullLocation();
4589
4590 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4591 return cxloc::translateSourceLocation(getCursorContext(C),
4592 TSInfo->getTypeLoc().getBeginLoc());
4593
4594 return cxloc::translateSourceLocation(getCursorContext(C),
4595 BaseSpec->getLocStart());
4596 }
4597
4598 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004599 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004600 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4601 }
4602
4603 case CXCursor_OverloadedDeclRef:
4604 return cxloc::translateSourceLocation(getCursorContext(C),
4605 getCursorOverloadedDeclRef(C).second);
4606
4607 default:
4608 // FIXME: Need a way to enumerate all non-reference cases.
4609 llvm_unreachable("Missed a reference kind");
4610 }
4611 }
4612
4613 if (clang_isExpression(C.kind))
4614 return cxloc::translateSourceLocation(getCursorContext(C),
4615 getLocationFromExpr(getCursorExpr(C)));
4616
4617 if (clang_isStatement(C.kind))
4618 return cxloc::translateSourceLocation(getCursorContext(C),
4619 getCursorStmt(C)->getLocStart());
4620
4621 if (C.kind == CXCursor_PreprocessingDirective) {
4622 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4623 return cxloc::translateSourceLocation(getCursorContext(C), L);
4624 }
4625
4626 if (C.kind == CXCursor_MacroExpansion) {
4627 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004628 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004629 return cxloc::translateSourceLocation(getCursorContext(C), L);
4630 }
4631
4632 if (C.kind == CXCursor_MacroDefinition) {
4633 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4634 return cxloc::translateSourceLocation(getCursorContext(C), L);
4635 }
4636
4637 if (C.kind == CXCursor_InclusionDirective) {
4638 SourceLocation L
4639 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4640 return cxloc::translateSourceLocation(getCursorContext(C), L);
4641 }
4642
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004643 if (clang_isAttribute(C.kind)) {
4644 SourceLocation L
4645 = cxcursor::getCursorAttr(C)->getLocation();
4646 return cxloc::translateSourceLocation(getCursorContext(C), L);
4647 }
4648
Guy Benyei11169dd2012-12-18 14:30:41 +00004649 if (!clang_isDeclaration(C.kind))
4650 return clang_getNullLocation();
4651
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004652 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004653 if (!D)
4654 return clang_getNullLocation();
4655
4656 SourceLocation Loc = D->getLocation();
4657 // FIXME: Multiple variables declared in a single declaration
4658 // currently lack the information needed to correctly determine their
4659 // ranges when accounting for the type-specifier. We use context
4660 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4661 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004662 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004663 if (!cxcursor::isFirstInDeclGroup(C))
4664 Loc = VD->getLocation();
4665 }
4666
4667 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004668 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004669 Loc = MD->getSelectorStartLoc();
4670
4671 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4672}
4673
4674} // end extern "C"
4675
4676CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4677 assert(TU);
4678
4679 // Guard against an invalid SourceLocation, or we may assert in one
4680 // of the following calls.
4681 if (SLoc.isInvalid())
4682 return clang_getNullCursor();
4683
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004684 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004685
4686 // Translate the given source location to make it point at the beginning of
4687 // the token under the cursor.
4688 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4689 CXXUnit->getASTContext().getLangOpts());
4690
4691 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4692 if (SLoc.isValid()) {
4693 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4694 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4695 /*VisitPreprocessorLast=*/true,
4696 /*VisitIncludedEntities=*/false,
4697 SourceLocation(SLoc));
4698 CursorVis.visitFileRegion();
4699 }
4700
4701 return Result;
4702}
4703
4704static SourceRange getRawCursorExtent(CXCursor C) {
4705 if (clang_isReference(C.kind)) {
4706 switch (C.kind) {
4707 case CXCursor_ObjCSuperClassRef:
4708 return getCursorObjCSuperClassRef(C).second;
4709
4710 case CXCursor_ObjCProtocolRef:
4711 return getCursorObjCProtocolRef(C).second;
4712
4713 case CXCursor_ObjCClassRef:
4714 return getCursorObjCClassRef(C).second;
4715
4716 case CXCursor_TypeRef:
4717 return getCursorTypeRef(C).second;
4718
4719 case CXCursor_TemplateRef:
4720 return getCursorTemplateRef(C).second;
4721
4722 case CXCursor_NamespaceRef:
4723 return getCursorNamespaceRef(C).second;
4724
4725 case CXCursor_MemberRef:
4726 return getCursorMemberRef(C).second;
4727
4728 case CXCursor_CXXBaseSpecifier:
4729 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4730
4731 case CXCursor_LabelRef:
4732 return getCursorLabelRef(C).second;
4733
4734 case CXCursor_OverloadedDeclRef:
4735 return getCursorOverloadedDeclRef(C).second;
4736
4737 case CXCursor_VariableRef:
4738 return getCursorVariableRef(C).second;
4739
4740 default:
4741 // FIXME: Need a way to enumerate all non-reference cases.
4742 llvm_unreachable("Missed a reference kind");
4743 }
4744 }
4745
4746 if (clang_isExpression(C.kind))
4747 return getCursorExpr(C)->getSourceRange();
4748
4749 if (clang_isStatement(C.kind))
4750 return getCursorStmt(C)->getSourceRange();
4751
4752 if (clang_isAttribute(C.kind))
4753 return getCursorAttr(C)->getRange();
4754
4755 if (C.kind == CXCursor_PreprocessingDirective)
4756 return cxcursor::getCursorPreprocessingDirective(C);
4757
4758 if (C.kind == CXCursor_MacroExpansion) {
4759 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004760 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004761 return TU->mapRangeFromPreamble(Range);
4762 }
4763
4764 if (C.kind == CXCursor_MacroDefinition) {
4765 ASTUnit *TU = getCursorASTUnit(C);
4766 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4767 return TU->mapRangeFromPreamble(Range);
4768 }
4769
4770 if (C.kind == CXCursor_InclusionDirective) {
4771 ASTUnit *TU = getCursorASTUnit(C);
4772 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4773 return TU->mapRangeFromPreamble(Range);
4774 }
4775
4776 if (C.kind == CXCursor_TranslationUnit) {
4777 ASTUnit *TU = getCursorASTUnit(C);
4778 FileID MainID = TU->getSourceManager().getMainFileID();
4779 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4780 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4781 return SourceRange(Start, End);
4782 }
4783
4784 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004785 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004786 if (!D)
4787 return SourceRange();
4788
4789 SourceRange R = D->getSourceRange();
4790 // FIXME: Multiple variables declared in a single declaration
4791 // currently lack the information needed to correctly determine their
4792 // ranges when accounting for the type-specifier. We use context
4793 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4794 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004795 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004796 if (!cxcursor::isFirstInDeclGroup(C))
4797 R.setBegin(VD->getLocation());
4798 }
4799 return R;
4800 }
4801 return SourceRange();
4802}
4803
4804/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4805/// the decl-specifier-seq for declarations.
4806static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4807 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004808 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004809 if (!D)
4810 return SourceRange();
4811
4812 SourceRange R = D->getSourceRange();
4813
4814 // Adjust the start of the location for declarations preceded by
4815 // declaration specifiers.
4816 SourceLocation StartLoc;
4817 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4818 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4819 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004820 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004821 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4822 StartLoc = TI->getTypeLoc().getLocStart();
4823 }
4824
4825 if (StartLoc.isValid() && R.getBegin().isValid() &&
4826 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4827 R.setBegin(StartLoc);
4828
4829 // FIXME: Multiple variables declared in a single declaration
4830 // currently lack the information needed to correctly determine their
4831 // ranges when accounting for the type-specifier. We use context
4832 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4833 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004834 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004835 if (!cxcursor::isFirstInDeclGroup(C))
4836 R.setBegin(VD->getLocation());
4837 }
4838
4839 return R;
4840 }
4841
4842 return getRawCursorExtent(C);
4843}
4844
4845extern "C" {
4846
4847CXSourceRange clang_getCursorExtent(CXCursor C) {
4848 SourceRange R = getRawCursorExtent(C);
4849 if (R.isInvalid())
4850 return clang_getNullRange();
4851
4852 return cxloc::translateSourceRange(getCursorContext(C), R);
4853}
4854
4855CXCursor clang_getCursorReferenced(CXCursor C) {
4856 if (clang_isInvalid(C.kind))
4857 return clang_getNullCursor();
4858
4859 CXTranslationUnit tu = getCursorTU(C);
4860 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004861 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004862 if (!D)
4863 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004864 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004865 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004866 if (const ObjCPropertyImplDecl *PropImpl =
4867 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004868 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4869 return MakeCXCursor(Property, tu);
4870
4871 return C;
4872 }
4873
4874 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004875 const Expr *E = getCursorExpr(C);
4876 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004877 if (D) {
4878 CXCursor declCursor = MakeCXCursor(D, tu);
4879 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4880 declCursor);
4881 return declCursor;
4882 }
4883
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004884 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004885 return MakeCursorOverloadedDeclRef(Ovl, tu);
4886
4887 return clang_getNullCursor();
4888 }
4889
4890 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004891 const Stmt *S = getCursorStmt(C);
4892 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004893 if (LabelDecl *label = Goto->getLabel())
4894 if (LabelStmt *labelS = label->getStmt())
4895 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4896
4897 return clang_getNullCursor();
4898 }
Richard Smith66a81862015-05-04 02:25:31 +00004899
Guy Benyei11169dd2012-12-18 14:30:41 +00004900 if (C.kind == CXCursor_MacroExpansion) {
Richard Smith66a81862015-05-04 02:25:31 +00004901 if (const MacroDefinitionRecord *Def =
4902 getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004903 return MakeMacroDefinitionCursor(Def, tu);
4904 }
4905
4906 if (!clang_isReference(C.kind))
4907 return clang_getNullCursor();
4908
4909 switch (C.kind) {
4910 case CXCursor_ObjCSuperClassRef:
4911 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4912
4913 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004914 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4915 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004916 return MakeCXCursor(Def, tu);
4917
4918 return MakeCXCursor(Prot, tu);
4919 }
4920
4921 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004922 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4923 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004924 return MakeCXCursor(Def, tu);
4925
4926 return MakeCXCursor(Class, tu);
4927 }
4928
4929 case CXCursor_TypeRef:
4930 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4931
4932 case CXCursor_TemplateRef:
4933 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4934
4935 case CXCursor_NamespaceRef:
4936 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4937
4938 case CXCursor_MemberRef:
4939 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4940
4941 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004942 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004943 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4944 tu ));
4945 }
4946
4947 case CXCursor_LabelRef:
4948 // FIXME: We end up faking the "parent" declaration here because we
4949 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004950 return MakeCXCursor(getCursorLabelRef(C).first,
4951 cxtu::getASTUnit(tu)->getASTContext()
4952 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004953 tu);
4954
4955 case CXCursor_OverloadedDeclRef:
4956 return C;
4957
4958 case CXCursor_VariableRef:
4959 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4960
4961 default:
4962 // We would prefer to enumerate all non-reference cursor kinds here.
4963 llvm_unreachable("Unhandled reference cursor kind");
4964 }
4965}
4966
4967CXCursor clang_getCursorDefinition(CXCursor C) {
4968 if (clang_isInvalid(C.kind))
4969 return clang_getNullCursor();
4970
4971 CXTranslationUnit TU = getCursorTU(C);
4972
4973 bool WasReference = false;
4974 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4975 C = clang_getCursorReferenced(C);
4976 WasReference = true;
4977 }
4978
4979 if (C.kind == CXCursor_MacroExpansion)
4980 return clang_getCursorReferenced(C);
4981
4982 if (!clang_isDeclaration(C.kind))
4983 return clang_getNullCursor();
4984
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004985 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004986 if (!D)
4987 return clang_getNullCursor();
4988
4989 switch (D->getKind()) {
4990 // Declaration kinds that don't really separate the notions of
4991 // declaration and definition.
4992 case Decl::Namespace:
4993 case Decl::Typedef:
4994 case Decl::TypeAlias:
4995 case Decl::TypeAliasTemplate:
4996 case Decl::TemplateTypeParm:
4997 case Decl::EnumConstant:
4998 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004999 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005000 case Decl::IndirectField:
5001 case Decl::ObjCIvar:
5002 case Decl::ObjCAtDefsField:
5003 case Decl::ImplicitParam:
5004 case Decl::ParmVar:
5005 case Decl::NonTypeTemplateParm:
5006 case Decl::TemplateTemplateParm:
5007 case Decl::ObjCCategoryImpl:
5008 case Decl::ObjCImplementation:
5009 case Decl::AccessSpec:
5010 case Decl::LinkageSpec:
5011 case Decl::ObjCPropertyImpl:
5012 case Decl::FileScopeAsm:
5013 case Decl::StaticAssert:
5014 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00005015 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00005016 case Decl::Label: // FIXME: Is this right??
5017 case Decl::ClassScopeFunctionSpecialization:
5018 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00005019 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00005020 return C;
5021
5022 // Declaration kinds that don't make any sense here, but are
5023 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00005024 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005025 case Decl::TranslationUnit:
Richard Smithf19e1272015-03-07 00:04:49 +00005026 case Decl::ExternCContext:
Guy Benyei11169dd2012-12-18 14:30:41 +00005027 break;
5028
5029 // Declaration kinds for which the definition is not resolvable.
5030 case Decl::UnresolvedUsingTypename:
5031 case Decl::UnresolvedUsingValue:
5032 break;
5033
5034 case Decl::UsingDirective:
5035 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
5036 TU);
5037
5038 case Decl::NamespaceAlias:
5039 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
5040
5041 case Decl::Enum:
5042 case Decl::Record:
5043 case Decl::CXXRecord:
5044 case Decl::ClassTemplateSpecialization:
5045 case Decl::ClassTemplatePartialSpecialization:
5046 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
5047 return MakeCXCursor(Def, TU);
5048 return clang_getNullCursor();
5049
5050 case Decl::Function:
5051 case Decl::CXXMethod:
5052 case Decl::CXXConstructor:
5053 case Decl::CXXDestructor:
5054 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00005055 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005056 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00005057 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005058 return clang_getNullCursor();
5059 }
5060
Larisse Voufo39a1e502013-08-06 01:03:05 +00005061 case Decl::Var:
5062 case Decl::VarTemplateSpecialization:
5063 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00005064 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005065 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005066 return MakeCXCursor(Def, TU);
5067 return clang_getNullCursor();
5068 }
5069
5070 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00005071 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005072 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
5073 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
5074 return clang_getNullCursor();
5075 }
5076
5077 case Decl::ClassTemplate: {
5078 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
5079 ->getDefinition())
5080 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
5081 TU);
5082 return clang_getNullCursor();
5083 }
5084
Larisse Voufo39a1e502013-08-06 01:03:05 +00005085 case Decl::VarTemplate: {
5086 if (VarDecl *Def =
5087 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
5088 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
5089 return clang_getNullCursor();
5090 }
5091
Guy Benyei11169dd2012-12-18 14:30:41 +00005092 case Decl::Using:
5093 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
5094 D->getLocation(), TU);
5095
5096 case Decl::UsingShadow:
5097 return clang_getCursorDefinition(
5098 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
5099 TU));
5100
5101 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005102 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005103 if (Method->isThisDeclarationADefinition())
5104 return C;
5105
5106 // Dig out the method definition in the associated
5107 // @implementation, if we have it.
5108 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005109 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005110 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
5111 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
5112 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
5113 Method->isInstanceMethod()))
5114 if (Def->isThisDeclarationADefinition())
5115 return MakeCXCursor(Def, TU);
5116
5117 return clang_getNullCursor();
5118 }
5119
5120 case Decl::ObjCCategory:
5121 if (ObjCCategoryImplDecl *Impl
5122 = cast<ObjCCategoryDecl>(D)->getImplementation())
5123 return MakeCXCursor(Impl, TU);
5124 return clang_getNullCursor();
5125
5126 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005127 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005128 return MakeCXCursor(Def, TU);
5129 return clang_getNullCursor();
5130
5131 case Decl::ObjCInterface: {
5132 // There are two notions of a "definition" for an Objective-C
5133 // class: the interface and its implementation. When we resolved a
5134 // reference to an Objective-C class, produce the @interface as
5135 // the definition; when we were provided with the interface,
5136 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005137 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005138 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005139 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005140 return MakeCXCursor(Def, TU);
5141 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
5142 return MakeCXCursor(Impl, TU);
5143 return clang_getNullCursor();
5144 }
5145
5146 case Decl::ObjCProperty:
5147 // FIXME: We don't really know where to find the
5148 // ObjCPropertyImplDecls that implement this property.
5149 return clang_getNullCursor();
5150
5151 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005152 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005153 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005154 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005155 return MakeCXCursor(Def, TU);
5156
5157 return clang_getNullCursor();
5158
5159 case Decl::Friend:
5160 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
5161 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5162 return clang_getNullCursor();
5163
5164 case Decl::FriendTemplate:
5165 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
5166 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5167 return clang_getNullCursor();
5168 }
5169
5170 return clang_getNullCursor();
5171}
5172
5173unsigned clang_isCursorDefinition(CXCursor C) {
5174 if (!clang_isDeclaration(C.kind))
5175 return 0;
5176
5177 return clang_getCursorDefinition(C) == C;
5178}
5179
5180CXCursor clang_getCanonicalCursor(CXCursor C) {
5181 if (!clang_isDeclaration(C.kind))
5182 return C;
5183
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005184 if (const Decl *D = getCursorDecl(C)) {
5185 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005186 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5187 return MakeCXCursor(CatD, getCursorTU(C));
5188
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005189 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5190 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00005191 return MakeCXCursor(IFD, getCursorTU(C));
5192
5193 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5194 }
5195
5196 return C;
5197}
5198
5199int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5200 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5201}
5202
5203unsigned clang_getNumOverloadedDecls(CXCursor C) {
5204 if (C.kind != CXCursor_OverloadedDeclRef)
5205 return 0;
5206
5207 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005208 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005209 return E->getNumDecls();
5210
5211 if (OverloadedTemplateStorage *S
5212 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5213 return S->size();
5214
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005215 const Decl *D = Storage.get<const Decl *>();
5216 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005217 return Using->shadow_size();
5218
5219 return 0;
5220}
5221
5222CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5223 if (cursor.kind != CXCursor_OverloadedDeclRef)
5224 return clang_getNullCursor();
5225
5226 if (index >= clang_getNumOverloadedDecls(cursor))
5227 return clang_getNullCursor();
5228
5229 CXTranslationUnit TU = getCursorTU(cursor);
5230 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005231 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005232 return MakeCXCursor(E->decls_begin()[index], TU);
5233
5234 if (OverloadedTemplateStorage *S
5235 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5236 return MakeCXCursor(S->begin()[index], TU);
5237
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005238 const Decl *D = Storage.get<const Decl *>();
5239 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005240 // FIXME: This is, unfortunately, linear time.
5241 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5242 std::advance(Pos, index);
5243 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5244 }
5245
5246 return clang_getNullCursor();
5247}
5248
5249void clang_getDefinitionSpellingAndExtent(CXCursor C,
5250 const char **startBuf,
5251 const char **endBuf,
5252 unsigned *startLine,
5253 unsigned *startColumn,
5254 unsigned *endLine,
5255 unsigned *endColumn) {
5256 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005257 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005258 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5259
5260 SourceManager &SM = FD->getASTContext().getSourceManager();
5261 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5262 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5263 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5264 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5265 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5266 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5267}
5268
5269
5270CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5271 unsigned PieceIndex) {
5272 RefNamePieces Pieces;
5273
5274 switch (C.kind) {
5275 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005276 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005277 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5278 E->getQualifierLoc().getSourceRange());
5279 break;
5280
5281 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005282 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005283 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
5284 E->getQualifierLoc().getSourceRange(),
5285 E->getOptionalExplicitTemplateArgs());
5286 break;
5287
5288 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005289 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005290 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005291 const Expr *Callee = OCE->getCallee();
5292 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005293 Callee = ICE->getSubExpr();
5294
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005295 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005296 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5297 DRE->getQualifierLoc().getSourceRange());
5298 }
5299 break;
5300
5301 default:
5302 break;
5303 }
5304
5305 if (Pieces.empty()) {
5306 if (PieceIndex == 0)
5307 return clang_getCursorExtent(C);
5308 } else if (PieceIndex < Pieces.size()) {
5309 SourceRange R = Pieces[PieceIndex];
5310 if (R.isValid())
5311 return cxloc::translateSourceRange(getCursorContext(C), R);
5312 }
5313
5314 return clang_getNullRange();
5315}
5316
5317void clang_enableStackTraces(void) {
5318 llvm::sys::PrintStackTraceOnErrorSignal();
5319}
5320
5321void clang_executeOnThread(void (*fn)(void*), void *user_data,
5322 unsigned stack_size) {
5323 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5324}
5325
5326} // end: extern "C"
5327
5328//===----------------------------------------------------------------------===//
5329// Token-based Operations.
5330//===----------------------------------------------------------------------===//
5331
5332/* CXToken layout:
5333 * int_data[0]: a CXTokenKind
5334 * int_data[1]: starting token location
5335 * int_data[2]: token length
5336 * int_data[3]: reserved
5337 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5338 * otherwise unused.
5339 */
5340extern "C" {
5341
5342CXTokenKind clang_getTokenKind(CXToken CXTok) {
5343 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5344}
5345
5346CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5347 switch (clang_getTokenKind(CXTok)) {
5348 case CXToken_Identifier:
5349 case CXToken_Keyword:
5350 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005351 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005352 ->getNameStart());
5353
5354 case CXToken_Literal: {
5355 // We have stashed the starting pointer in the ptr_data field. Use it.
5356 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005357 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005358 }
5359
5360 case CXToken_Punctuation:
5361 case CXToken_Comment:
5362 break;
5363 }
5364
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005365 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005366 LOG_BAD_TU(TU);
5367 return cxstring::createEmpty();
5368 }
5369
Guy Benyei11169dd2012-12-18 14:30:41 +00005370 // We have to find the starting buffer pointer the hard way, by
5371 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005372 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005373 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005374 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005375
5376 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5377 std::pair<FileID, unsigned> LocInfo
5378 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5379 bool Invalid = false;
5380 StringRef Buffer
5381 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5382 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005383 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005384
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005385 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005386}
5387
5388CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005389 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005390 LOG_BAD_TU(TU);
5391 return clang_getNullLocation();
5392 }
5393
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005394 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005395 if (!CXXUnit)
5396 return clang_getNullLocation();
5397
5398 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5399 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5400}
5401
5402CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005403 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005404 LOG_BAD_TU(TU);
5405 return clang_getNullRange();
5406 }
5407
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005408 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005409 if (!CXXUnit)
5410 return clang_getNullRange();
5411
5412 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5413 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5414}
5415
5416static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5417 SmallVectorImpl<CXToken> &CXTokens) {
5418 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5419 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005420 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005421 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005422 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005423
5424 // Cannot tokenize across files.
5425 if (BeginLocInfo.first != EndLocInfo.first)
5426 return;
5427
5428 // Create a lexer
5429 bool Invalid = false;
5430 StringRef Buffer
5431 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5432 if (Invalid)
5433 return;
5434
5435 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5436 CXXUnit->getASTContext().getLangOpts(),
5437 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5438 Lex.SetCommentRetentionState(true);
5439
5440 // Lex tokens until we hit the end of the range.
5441 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5442 Token Tok;
5443 bool previousWasAt = false;
5444 do {
5445 // Lex the next token
5446 Lex.LexFromRawLexer(Tok);
5447 if (Tok.is(tok::eof))
5448 break;
5449
5450 // Initialize the CXToken.
5451 CXToken CXTok;
5452
5453 // - Common fields
5454 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5455 CXTok.int_data[2] = Tok.getLength();
5456 CXTok.int_data[3] = 0;
5457
5458 // - Kind-specific fields
5459 if (Tok.isLiteral()) {
5460 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005461 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005462 } else if (Tok.is(tok::raw_identifier)) {
5463 // Lookup the identifier to determine whether we have a keyword.
5464 IdentifierInfo *II
5465 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5466
5467 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5468 CXTok.int_data[0] = CXToken_Keyword;
5469 }
5470 else {
5471 CXTok.int_data[0] = Tok.is(tok::identifier)
5472 ? CXToken_Identifier
5473 : CXToken_Keyword;
5474 }
5475 CXTok.ptr_data = II;
5476 } else if (Tok.is(tok::comment)) {
5477 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005478 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005479 } else {
5480 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005481 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005482 }
5483 CXTokens.push_back(CXTok);
5484 previousWasAt = Tok.is(tok::at);
5485 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5486}
5487
5488void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5489 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005490 LOG_FUNC_SECTION {
5491 *Log << TU << ' ' << Range;
5492 }
5493
Guy Benyei11169dd2012-12-18 14:30:41 +00005494 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005495 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005496 if (NumTokens)
5497 *NumTokens = 0;
5498
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005499 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005500 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005501 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005502 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005503
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005504 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005505 if (!CXXUnit || !Tokens || !NumTokens)
5506 return;
5507
5508 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5509
5510 SourceRange R = cxloc::translateCXSourceRange(Range);
5511 if (R.isInvalid())
5512 return;
5513
5514 SmallVector<CXToken, 32> CXTokens;
5515 getTokens(CXXUnit, R, CXTokens);
5516
5517 if (CXTokens.empty())
5518 return;
5519
5520 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5521 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5522 *NumTokens = CXTokens.size();
5523}
5524
5525void clang_disposeTokens(CXTranslationUnit TU,
5526 CXToken *Tokens, unsigned NumTokens) {
5527 free(Tokens);
5528}
5529
5530} // end: extern "C"
5531
5532//===----------------------------------------------------------------------===//
5533// Token annotation APIs.
5534//===----------------------------------------------------------------------===//
5535
Guy Benyei11169dd2012-12-18 14:30:41 +00005536static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5537 CXCursor parent,
5538 CXClientData client_data);
5539static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5540 CXClientData client_data);
5541
5542namespace {
5543class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005544 CXToken *Tokens;
5545 CXCursor *Cursors;
5546 unsigned NumTokens;
5547 unsigned TokIdx;
5548 unsigned PreprocessingTokIdx;
5549 CursorVisitor AnnotateVis;
5550 SourceManager &SrcMgr;
5551 bool HasContextSensitiveKeywords;
5552
5553 struct PostChildrenInfo {
5554 CXCursor Cursor;
5555 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005556 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005557 unsigned BeforeChildrenTokenIdx;
5558 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005559 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005560
5561 CXToken &getTok(unsigned Idx) {
5562 assert(Idx < NumTokens);
5563 return Tokens[Idx];
5564 }
5565 const CXToken &getTok(unsigned Idx) const {
5566 assert(Idx < NumTokens);
5567 return Tokens[Idx];
5568 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005569 bool MoreTokens() const { return TokIdx < NumTokens; }
5570 unsigned NextToken() const { return TokIdx; }
5571 void AdvanceToken() { ++TokIdx; }
5572 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005573 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005574 }
5575 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005576 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005577 }
5578 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005579 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005580 }
5581
5582 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005583 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005584 SourceRange);
5585
5586public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005587 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005588 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005589 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005590 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005591 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005592 AnnotateTokensVisitor, this,
5593 /*VisitPreprocessorLast=*/true,
5594 /*VisitIncludedEntities=*/false,
5595 RegionOfInterest,
5596 /*VisitDeclsOnly=*/false,
5597 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005598 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005599 HasContextSensitiveKeywords(false) { }
5600
5601 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5602 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5603 bool postVisitChildren(CXCursor cursor);
5604 void AnnotateTokens();
5605
5606 /// \brief Determine whether the annotator saw any cursors that have
5607 /// context-sensitive keywords.
5608 bool hasContextSensitiveKeywords() const {
5609 return HasContextSensitiveKeywords;
5610 }
5611
5612 ~AnnotateTokensWorker() {
5613 assert(PostChildrenInfos.empty());
5614 }
5615};
5616}
5617
5618void AnnotateTokensWorker::AnnotateTokens() {
5619 // Walk the AST within the region of interest, annotating tokens
5620 // along the way.
5621 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005622}
Guy Benyei11169dd2012-12-18 14:30:41 +00005623
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005624static inline void updateCursorAnnotation(CXCursor &Cursor,
5625 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005626 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005627 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005628 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005629}
5630
5631/// \brief It annotates and advances tokens with a cursor until the comparison
5632//// between the cursor location and the source range is the same as
5633/// \arg compResult.
5634///
5635/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5636/// Pass RangeOverlap to annotate tokens inside a range.
5637void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5638 RangeComparisonResult compResult,
5639 SourceRange range) {
5640 while (MoreTokens()) {
5641 const unsigned I = NextToken();
5642 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005643 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5644 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005645
5646 SourceLocation TokLoc = GetTokenLoc(I);
5647 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005648 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005649 AdvanceToken();
5650 continue;
5651 }
5652 break;
5653 }
5654}
5655
5656/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005657/// \returns true if it advanced beyond all macro tokens, false otherwise.
5658bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005659 CXCursor updateC,
5660 RangeComparisonResult compResult,
5661 SourceRange range) {
5662 assert(MoreTokens());
5663 assert(isFunctionMacroToken(NextToken()) &&
5664 "Should be called only for macro arg tokens");
5665
5666 // This works differently than annotateAndAdvanceTokens; because expanded
5667 // macro arguments can have arbitrary translation-unit source order, we do not
5668 // advance the token index one by one until a token fails the range test.
5669 // We only advance once past all of the macro arg tokens if all of them
5670 // pass the range test. If one of them fails we keep the token index pointing
5671 // at the start of the macro arg tokens so that the failing token will be
5672 // annotated by a subsequent annotation try.
5673
5674 bool atLeastOneCompFail = false;
5675
5676 unsigned I = NextToken();
5677 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5678 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5679 if (TokLoc.isFileID())
5680 continue; // not macro arg token, it's parens or comma.
5681 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5682 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5683 Cursors[I] = updateC;
5684 } else
5685 atLeastOneCompFail = true;
5686 }
5687
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005688 if (atLeastOneCompFail)
5689 return false;
5690
5691 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5692 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005693}
5694
5695enum CXChildVisitResult
5696AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005697 SourceRange cursorRange = getRawCursorExtent(cursor);
5698 if (cursorRange.isInvalid())
5699 return CXChildVisit_Recurse;
5700
5701 if (!HasContextSensitiveKeywords) {
5702 // Objective-C properties can have context-sensitive keywords.
5703 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005704 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005705 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5706 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5707 }
5708 // Objective-C methods can have context-sensitive keywords.
5709 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5710 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005711 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005712 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5713 if (Method->getObjCDeclQualifier())
5714 HasContextSensitiveKeywords = true;
5715 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005716 for (const auto *P : Method->params()) {
5717 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005718 HasContextSensitiveKeywords = true;
5719 break;
5720 }
5721 }
5722 }
5723 }
5724 }
5725 // C++ methods can have context-sensitive keywords.
5726 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005727 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005728 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5729 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5730 HasContextSensitiveKeywords = true;
5731 }
5732 }
5733 // C++ classes can have context-sensitive keywords.
5734 else if (cursor.kind == CXCursor_StructDecl ||
5735 cursor.kind == CXCursor_ClassDecl ||
5736 cursor.kind == CXCursor_ClassTemplate ||
5737 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005738 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005739 if (D->hasAttr<FinalAttr>())
5740 HasContextSensitiveKeywords = true;
5741 }
5742 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005743
5744 // Don't override a property annotation with its getter/setter method.
5745 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5746 parent.kind == CXCursor_ObjCPropertyDecl)
5747 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005748
5749 if (clang_isPreprocessing(cursor.kind)) {
5750 // Items in the preprocessing record are kept separate from items in
5751 // declarations, so we keep a separate token index.
5752 unsigned SavedTokIdx = TokIdx;
5753 TokIdx = PreprocessingTokIdx;
5754
5755 // Skip tokens up until we catch up to the beginning of the preprocessing
5756 // entry.
5757 while (MoreTokens()) {
5758 const unsigned I = NextToken();
5759 SourceLocation TokLoc = GetTokenLoc(I);
5760 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5761 case RangeBefore:
5762 AdvanceToken();
5763 continue;
5764 case RangeAfter:
5765 case RangeOverlap:
5766 break;
5767 }
5768 break;
5769 }
5770
5771 // Look at all of the tokens within this range.
5772 while (MoreTokens()) {
5773 const unsigned I = NextToken();
5774 SourceLocation TokLoc = GetTokenLoc(I);
5775 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5776 case RangeBefore:
5777 llvm_unreachable("Infeasible");
5778 case RangeAfter:
5779 break;
5780 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005781 // For macro expansions, just note where the beginning of the macro
5782 // expansion occurs.
5783 if (cursor.kind == CXCursor_MacroExpansion) {
5784 if (TokLoc == cursorRange.getBegin())
5785 Cursors[I] = cursor;
5786 AdvanceToken();
5787 break;
5788 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005789 // We may have already annotated macro names inside macro definitions.
5790 if (Cursors[I].kind != CXCursor_MacroExpansion)
5791 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005792 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005793 continue;
5794 }
5795 break;
5796 }
5797
5798 // Save the preprocessing token index; restore the non-preprocessing
5799 // token index.
5800 PreprocessingTokIdx = TokIdx;
5801 TokIdx = SavedTokIdx;
5802 return CXChildVisit_Recurse;
5803 }
5804
5805 if (cursorRange.isInvalid())
5806 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005807
5808 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005809 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005810 const enum CXCursorKind K = clang_getCursorKind(parent);
5811 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005812 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5813 // Attributes are annotated out-of-order, skip tokens until we reach it.
5814 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005815 ? clang_getNullCursor() : parent;
5816
5817 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5818
5819 // Avoid having the cursor of an expression "overwrite" the annotation of the
5820 // variable declaration that it belongs to.
5821 // This can happen for C++ constructor expressions whose range generally
5822 // include the variable declaration, e.g.:
5823 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005824 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005825 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005826 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005827 const unsigned I = NextToken();
5828 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5829 E->getLocStart() == D->getLocation() &&
5830 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005831 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005832 AdvanceToken();
5833 }
5834 }
5835 }
5836
5837 // Before recursing into the children keep some state that we are going
5838 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5839 // extra work after the child nodes are visited.
5840 // Note that we don't call VisitChildren here to avoid traversing statements
5841 // code-recursively which can blow the stack.
5842
5843 PostChildrenInfo Info;
5844 Info.Cursor = cursor;
5845 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005846 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005847 Info.BeforeChildrenTokenIdx = NextToken();
5848 PostChildrenInfos.push_back(Info);
5849
5850 return CXChildVisit_Recurse;
5851}
5852
5853bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5854 if (PostChildrenInfos.empty())
5855 return false;
5856 const PostChildrenInfo &Info = PostChildrenInfos.back();
5857 if (!clang_equalCursors(Info.Cursor, cursor))
5858 return false;
5859
5860 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5861 const unsigned AfterChildren = NextToken();
5862 SourceRange cursorRange = Info.CursorRange;
5863
5864 // Scan the tokens that are at the end of the cursor, but are not captured
5865 // but the child cursors.
5866 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5867
5868 // Scan the tokens that are at the beginning of the cursor, but are not
5869 // capture by the child cursors.
5870 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5871 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5872 break;
5873
5874 Cursors[I] = cursor;
5875 }
5876
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005877 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5878 // encountered the attribute cursor.
5879 if (clang_isAttribute(cursor.kind))
5880 TokIdx = Info.BeforeReachingCursorIdx;
5881
Guy Benyei11169dd2012-12-18 14:30:41 +00005882 PostChildrenInfos.pop_back();
5883 return false;
5884}
5885
5886static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5887 CXCursor parent,
5888 CXClientData client_data) {
5889 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5890}
5891
5892static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5893 CXClientData client_data) {
5894 return static_cast<AnnotateTokensWorker*>(client_data)->
5895 postVisitChildren(cursor);
5896}
5897
5898namespace {
5899
5900/// \brief Uses the macro expansions in the preprocessing record to find
5901/// and mark tokens that are macro arguments. This info is used by the
5902/// AnnotateTokensWorker.
5903class MarkMacroArgTokensVisitor {
5904 SourceManager &SM;
5905 CXToken *Tokens;
5906 unsigned NumTokens;
5907 unsigned CurIdx;
5908
5909public:
5910 MarkMacroArgTokensVisitor(SourceManager &SM,
5911 CXToken *tokens, unsigned numTokens)
5912 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5913
5914 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5915 if (cursor.kind != CXCursor_MacroExpansion)
5916 return CXChildVisit_Continue;
5917
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005918 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005919 if (macroRange.getBegin() == macroRange.getEnd())
5920 return CXChildVisit_Continue; // it's not a function macro.
5921
5922 for (; CurIdx < NumTokens; ++CurIdx) {
5923 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5924 macroRange.getBegin()))
5925 break;
5926 }
5927
5928 if (CurIdx == NumTokens)
5929 return CXChildVisit_Break;
5930
5931 for (; CurIdx < NumTokens; ++CurIdx) {
5932 SourceLocation tokLoc = getTokenLoc(CurIdx);
5933 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5934 break;
5935
5936 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5937 }
5938
5939 if (CurIdx == NumTokens)
5940 return CXChildVisit_Break;
5941
5942 return CXChildVisit_Continue;
5943 }
5944
5945private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005946 CXToken &getTok(unsigned Idx) {
5947 assert(Idx < NumTokens);
5948 return Tokens[Idx];
5949 }
5950 const CXToken &getTok(unsigned Idx) const {
5951 assert(Idx < NumTokens);
5952 return Tokens[Idx];
5953 }
5954
Guy Benyei11169dd2012-12-18 14:30:41 +00005955 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005956 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005957 }
5958
5959 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5960 // The third field is reserved and currently not used. Use it here
5961 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005962 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005963 }
5964};
5965
5966} // end anonymous namespace
5967
5968static CXChildVisitResult
5969MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5970 CXClientData client_data) {
5971 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5972 parent);
5973}
5974
5975namespace {
5976 struct clang_annotateTokens_Data {
5977 CXTranslationUnit TU;
5978 ASTUnit *CXXUnit;
5979 CXToken *Tokens;
5980 unsigned NumTokens;
5981 CXCursor *Cursors;
5982 };
5983}
5984
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005985/// \brief Used by \c annotatePreprocessorTokens.
5986/// \returns true if lexing was finished, false otherwise.
5987static bool lexNext(Lexer &Lex, Token &Tok,
5988 unsigned &NextIdx, unsigned NumTokens) {
5989 if (NextIdx >= NumTokens)
5990 return true;
5991
5992 ++NextIdx;
5993 Lex.LexFromRawLexer(Tok);
5994 if (Tok.is(tok::eof))
5995 return true;
5996
5997 return false;
5998}
5999
Guy Benyei11169dd2012-12-18 14:30:41 +00006000static void annotatePreprocessorTokens(CXTranslationUnit TU,
6001 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006002 CXCursor *Cursors,
6003 CXToken *Tokens,
6004 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006005 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006006
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006007 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00006008 SourceManager &SourceMgr = CXXUnit->getSourceManager();
6009 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006010 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00006011 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006012 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00006013
6014 if (BeginLocInfo.first != EndLocInfo.first)
6015 return;
6016
6017 StringRef Buffer;
6018 bool Invalid = false;
6019 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
6020 if (Buffer.empty() || Invalid)
6021 return;
6022
6023 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
6024 CXXUnit->getASTContext().getLangOpts(),
6025 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
6026 Buffer.end());
6027 Lex.SetCommentRetentionState(true);
6028
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006029 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006030 // Lex tokens in raw mode until we hit the end of the range, to avoid
6031 // entering #includes or expanding macros.
6032 while (true) {
6033 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006034 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6035 break;
6036 unsigned TokIdx = NextIdx-1;
6037 assert(Tok.getLocation() ==
6038 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006039
6040 reprocess:
6041 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006042 // We have found a preprocessing directive. Annotate the tokens
6043 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00006044 //
6045 // FIXME: Some simple tests here could identify macro definitions and
6046 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006047
6048 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006049 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6050 break;
6051
Craig Topper69186e72014-06-08 08:38:04 +00006052 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00006053 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006054 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6055 break;
6056
6057 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00006058 IdentifierInfo &II =
6059 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006060 SourceLocation MappedTokLoc =
6061 CXXUnit->mapLocationToPreamble(Tok.getLocation());
6062 MI = getMacroInfo(II, MappedTokLoc, TU);
6063 }
6064 }
6065
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006066 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00006067 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006068 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
6069 finished = true;
6070 break;
6071 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006072 // If we are in a macro definition, check if the token was ever a
6073 // macro name and annotate it if that's the case.
6074 if (MI) {
6075 SourceLocation SaveLoc = Tok.getLocation();
6076 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
Richard Smith66a81862015-05-04 02:25:31 +00006077 MacroDefinitionRecord *MacroDef =
6078 checkForMacroInMacroDefinition(MI, Tok, TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006079 Tok.setLocation(SaveLoc);
6080 if (MacroDef)
Richard Smith66a81862015-05-04 02:25:31 +00006081 Cursors[NextIdx - 1] =
6082 MakeMacroExpansionCursor(MacroDef, Tok.getLocation(), TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006083 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006084 } while (!Tok.isAtStartOfLine());
6085
6086 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
6087 assert(TokIdx <= LastIdx);
6088 SourceLocation EndLoc =
6089 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
6090 CXCursor Cursor =
6091 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
6092
6093 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006094 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006095
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006096 if (finished)
6097 break;
6098 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00006099 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006100 }
6101}
6102
6103// This gets run a separate thread to avoid stack blowout.
6104static void clang_annotateTokensImpl(void *UserData) {
6105 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
6106 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
6107 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
6108 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
6109 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
6110
Dmitri Gribenko183436e2013-01-26 21:49:50 +00006111 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006112 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
6113 setThreadBackgroundPriority();
6114
6115 // Determine the region of interest, which contains all of the tokens.
6116 SourceRange RegionOfInterest;
6117 RegionOfInterest.setBegin(
6118 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
6119 RegionOfInterest.setEnd(
6120 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
6121 Tokens[NumTokens-1])));
6122
Guy Benyei11169dd2012-12-18 14:30:41 +00006123 // Relex the tokens within the source range to look for preprocessing
6124 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006125 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006126
6127 // If begin location points inside a macro argument, set it to the expansion
6128 // location so we can have the full context when annotating semantically.
6129 {
6130 SourceManager &SM = CXXUnit->getSourceManager();
6131 SourceLocation Loc =
6132 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
6133 if (Loc.isMacroID())
6134 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
6135 }
6136
Guy Benyei11169dd2012-12-18 14:30:41 +00006137 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
6138 // Search and mark tokens that are macro argument expansions.
6139 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
6140 Tokens, NumTokens);
6141 CursorVisitor MacroArgMarker(TU,
6142 MarkMacroArgTokensVisitorDelegate, &Visitor,
6143 /*VisitPreprocessorLast=*/true,
6144 /*VisitIncludedEntities=*/false,
6145 RegionOfInterest);
6146 MacroArgMarker.visitPreprocessedEntitiesInRegion();
6147 }
6148
6149 // Annotate all of the source locations in the region of interest that map to
6150 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006151 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00006152
6153 // FIXME: We use a ridiculous stack size here because the data-recursion
6154 // algorithm uses a large stack frame than the non-data recursive version,
6155 // and AnnotationTokensWorker currently transforms the data-recursion
6156 // algorithm back into a traditional recursion by explicitly calling
6157 // VisitChildren(). We will need to remove this explicit recursive call.
6158 W.AnnotateTokens();
6159
6160 // If we ran into any entities that involve context-sensitive keywords,
6161 // take another pass through the tokens to mark them as such.
6162 if (W.hasContextSensitiveKeywords()) {
6163 for (unsigned I = 0; I != NumTokens; ++I) {
6164 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
6165 continue;
6166
6167 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
6168 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006169 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006170 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
6171 if (Property->getPropertyAttributesAsWritten() != 0 &&
6172 llvm::StringSwitch<bool>(II->getName())
6173 .Case("readonly", true)
6174 .Case("assign", true)
6175 .Case("unsafe_unretained", true)
6176 .Case("readwrite", true)
6177 .Case("retain", true)
6178 .Case("copy", true)
6179 .Case("nonatomic", true)
6180 .Case("atomic", true)
6181 .Case("getter", true)
6182 .Case("setter", true)
6183 .Case("strong", true)
6184 .Case("weak", true)
6185 .Default(false))
6186 Tokens[I].int_data[0] = CXToken_Keyword;
6187 }
6188 continue;
6189 }
6190
6191 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6192 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6193 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6194 if (llvm::StringSwitch<bool>(II->getName())
6195 .Case("in", true)
6196 .Case("out", true)
6197 .Case("inout", true)
6198 .Case("oneway", true)
6199 .Case("bycopy", true)
6200 .Case("byref", true)
6201 .Default(false))
6202 Tokens[I].int_data[0] = CXToken_Keyword;
6203 continue;
6204 }
6205
6206 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6207 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6208 Tokens[I].int_data[0] = CXToken_Keyword;
6209 continue;
6210 }
6211 }
6212 }
6213}
6214
6215extern "C" {
6216
6217void clang_annotateTokens(CXTranslationUnit TU,
6218 CXToken *Tokens, unsigned NumTokens,
6219 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006220 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006221 LOG_BAD_TU(TU);
6222 return;
6223 }
6224 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006225 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006226 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006227 }
6228
6229 LOG_FUNC_SECTION {
6230 *Log << TU << ' ';
6231 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6232 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6233 *Log << clang_getRange(bloc, eloc);
6234 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006235
6236 // Any token we don't specifically annotate will have a NULL cursor.
6237 CXCursor C = clang_getNullCursor();
6238 for (unsigned I = 0; I != NumTokens; ++I)
6239 Cursors[I] = C;
6240
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006241 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006242 if (!CXXUnit)
6243 return;
6244
6245 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
6246
6247 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
6248 llvm::CrashRecoveryContext CRC;
6249 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
6250 GetSafetyThreadStackSize() * 2)) {
6251 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6252 }
6253}
6254
6255} // end: extern "C"
6256
6257//===----------------------------------------------------------------------===//
6258// Operations for querying linkage of a cursor.
6259//===----------------------------------------------------------------------===//
6260
6261extern "C" {
6262CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6263 if (!clang_isDeclaration(cursor.kind))
6264 return CXLinkage_Invalid;
6265
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006266 const Decl *D = cxcursor::getCursorDecl(cursor);
6267 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006268 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006269 case NoLinkage:
6270 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006271 case InternalLinkage: return CXLinkage_Internal;
6272 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6273 case ExternalLinkage: return CXLinkage_External;
6274 };
6275
6276 return CXLinkage_Invalid;
6277}
6278} // end: extern "C"
6279
6280//===----------------------------------------------------------------------===//
6281// Operations for querying language of a cursor.
6282//===----------------------------------------------------------------------===//
6283
6284static CXLanguageKind getDeclLanguage(const Decl *D) {
6285 if (!D)
6286 return CXLanguage_C;
6287
6288 switch (D->getKind()) {
6289 default:
6290 break;
6291 case Decl::ImplicitParam:
6292 case Decl::ObjCAtDefsField:
6293 case Decl::ObjCCategory:
6294 case Decl::ObjCCategoryImpl:
6295 case Decl::ObjCCompatibleAlias:
6296 case Decl::ObjCImplementation:
6297 case Decl::ObjCInterface:
6298 case Decl::ObjCIvar:
6299 case Decl::ObjCMethod:
6300 case Decl::ObjCProperty:
6301 case Decl::ObjCPropertyImpl:
6302 case Decl::ObjCProtocol:
6303 return CXLanguage_ObjC;
6304 case Decl::CXXConstructor:
6305 case Decl::CXXConversion:
6306 case Decl::CXXDestructor:
6307 case Decl::CXXMethod:
6308 case Decl::CXXRecord:
6309 case Decl::ClassTemplate:
6310 case Decl::ClassTemplatePartialSpecialization:
6311 case Decl::ClassTemplateSpecialization:
6312 case Decl::Friend:
6313 case Decl::FriendTemplate:
6314 case Decl::FunctionTemplate:
6315 case Decl::LinkageSpec:
6316 case Decl::Namespace:
6317 case Decl::NamespaceAlias:
6318 case Decl::NonTypeTemplateParm:
6319 case Decl::StaticAssert:
6320 case Decl::TemplateTemplateParm:
6321 case Decl::TemplateTypeParm:
6322 case Decl::UnresolvedUsingTypename:
6323 case Decl::UnresolvedUsingValue:
6324 case Decl::Using:
6325 case Decl::UsingDirective:
6326 case Decl::UsingShadow:
6327 return CXLanguage_CPlusPlus;
6328 }
6329
6330 return CXLanguage_C;
6331}
6332
6333extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006334
6335static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6336 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
6337 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00006338
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006339 switch (D->getAvailability()) {
6340 case AR_Available:
6341 case AR_NotYetIntroduced:
6342 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006343 return getCursorAvailabilityForDecl(
6344 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006345 return CXAvailability_Available;
6346
6347 case AR_Deprecated:
6348 return CXAvailability_Deprecated;
6349
6350 case AR_Unavailable:
6351 return CXAvailability_NotAvailable;
6352 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006353
6354 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006355}
6356
Guy Benyei11169dd2012-12-18 14:30:41 +00006357enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6358 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006359 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6360 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006361
6362 return CXAvailability_Available;
6363}
6364
6365static CXVersion convertVersion(VersionTuple In) {
6366 CXVersion Out = { -1, -1, -1 };
6367 if (In.empty())
6368 return Out;
6369
6370 Out.Major = In.getMajor();
6371
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006372 Optional<unsigned> Minor = In.getMinor();
6373 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006374 Out.Minor = *Minor;
6375 else
6376 return Out;
6377
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006378 Optional<unsigned> Subminor = In.getSubminor();
6379 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006380 Out.Subminor = *Subminor;
6381
6382 return Out;
6383}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006384
6385static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6386 int *always_deprecated,
6387 CXString *deprecated_message,
6388 int *always_unavailable,
6389 CXString *unavailable_message,
6390 CXPlatformAvailability *availability,
6391 int availability_size) {
6392 bool HadAvailAttr = false;
6393 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006394 for (auto A : D->attrs()) {
6395 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006396 HadAvailAttr = true;
6397 if (always_deprecated)
6398 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006399 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006400 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006401 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006402 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006403 continue;
6404 }
6405
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006406 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006407 HadAvailAttr = true;
6408 if (always_unavailable)
6409 *always_unavailable = 1;
6410 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006411 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006412 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6413 }
6414 continue;
6415 }
6416
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006417 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006418 HadAvailAttr = true;
6419 if (N < availability_size) {
6420 availability[N].Platform
6421 = cxstring::createDup(Avail->getPlatform()->getName());
6422 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6423 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6424 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6425 availability[N].Unavailable = Avail->getUnavailable();
6426 availability[N].Message = cxstring::createDup(Avail->getMessage());
6427 }
6428 ++N;
6429 }
6430 }
6431
6432 if (!HadAvailAttr)
6433 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6434 return getCursorPlatformAvailabilityForDecl(
6435 cast<Decl>(EnumConst->getDeclContext()),
6436 always_deprecated,
6437 deprecated_message,
6438 always_unavailable,
6439 unavailable_message,
6440 availability,
6441 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006442
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006443 return N;
6444}
6445
Guy Benyei11169dd2012-12-18 14:30:41 +00006446int clang_getCursorPlatformAvailability(CXCursor cursor,
6447 int *always_deprecated,
6448 CXString *deprecated_message,
6449 int *always_unavailable,
6450 CXString *unavailable_message,
6451 CXPlatformAvailability *availability,
6452 int availability_size) {
6453 if (always_deprecated)
6454 *always_deprecated = 0;
6455 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006456 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006457 if (always_unavailable)
6458 *always_unavailable = 0;
6459 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006460 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006461
Guy Benyei11169dd2012-12-18 14:30:41 +00006462 if (!clang_isDeclaration(cursor.kind))
6463 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006464
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006465 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006466 if (!D)
6467 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006468
6469 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6470 deprecated_message,
6471 always_unavailable,
6472 unavailable_message,
6473 availability,
6474 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006475}
6476
6477void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6478 clang_disposeString(availability->Platform);
6479 clang_disposeString(availability->Message);
6480}
6481
6482CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6483 if (clang_isDeclaration(cursor.kind))
6484 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6485
6486 return CXLanguage_Invalid;
6487}
6488
6489 /// \brief If the given cursor is the "templated" declaration
6490 /// descibing a class or function template, return the class or
6491 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006492static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006493 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006494 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006495
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006496 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006497 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6498 return FunTmpl;
6499
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006500 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006501 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6502 return ClassTmpl;
6503
6504 return D;
6505}
6506
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006507
6508enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
6509 StorageClass sc = SC_None;
6510 const Decl *D = getCursorDecl(C);
6511 if (D) {
6512 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
6513 sc = FD->getStorageClass();
6514 } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
6515 sc = VD->getStorageClass();
6516 } else {
6517 return CX_SC_Invalid;
6518 }
6519 } else {
6520 return CX_SC_Invalid;
6521 }
6522 switch (sc) {
6523 case SC_None:
6524 return CX_SC_None;
6525 case SC_Extern:
6526 return CX_SC_Extern;
6527 case SC_Static:
6528 return CX_SC_Static;
6529 case SC_PrivateExtern:
6530 return CX_SC_PrivateExtern;
6531 case SC_OpenCLWorkGroupLocal:
6532 return CX_SC_OpenCLWorkGroupLocal;
6533 case SC_Auto:
6534 return CX_SC_Auto;
6535 case SC_Register:
6536 return CX_SC_Register;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006537 }
Kaelyn Takataab61e702014-10-15 18:03:26 +00006538 llvm_unreachable("Unhandled storage class!");
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006539}
6540
Guy Benyei11169dd2012-12-18 14:30:41 +00006541CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6542 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006543 if (const Decl *D = getCursorDecl(cursor)) {
6544 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006545 if (!DC)
6546 return clang_getNullCursor();
6547
6548 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6549 getCursorTU(cursor));
6550 }
6551 }
6552
6553 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006554 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006555 return MakeCXCursor(D, getCursorTU(cursor));
6556 }
6557
6558 return clang_getNullCursor();
6559}
6560
6561CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6562 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006563 if (const Decl *D = getCursorDecl(cursor)) {
6564 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006565 if (!DC)
6566 return clang_getNullCursor();
6567
6568 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6569 getCursorTU(cursor));
6570 }
6571 }
6572
6573 // FIXME: Note that we can't easily compute the lexical context of a
6574 // statement or expression, so we return nothing.
6575 return clang_getNullCursor();
6576}
6577
6578CXFile clang_getIncludedFile(CXCursor cursor) {
6579 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006580 return nullptr;
6581
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006582 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006583 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006584}
6585
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006586unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6587 if (C.kind != CXCursor_ObjCPropertyDecl)
6588 return CXObjCPropertyAttr_noattr;
6589
6590 unsigned Result = CXObjCPropertyAttr_noattr;
6591 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6592 ObjCPropertyDecl::PropertyAttributeKind Attr =
6593 PD->getPropertyAttributesAsWritten();
6594
6595#define SET_CXOBJCPROP_ATTR(A) \
6596 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6597 Result |= CXObjCPropertyAttr_##A
6598 SET_CXOBJCPROP_ATTR(readonly);
6599 SET_CXOBJCPROP_ATTR(getter);
6600 SET_CXOBJCPROP_ATTR(assign);
6601 SET_CXOBJCPROP_ATTR(readwrite);
6602 SET_CXOBJCPROP_ATTR(retain);
6603 SET_CXOBJCPROP_ATTR(copy);
6604 SET_CXOBJCPROP_ATTR(nonatomic);
6605 SET_CXOBJCPROP_ATTR(setter);
6606 SET_CXOBJCPROP_ATTR(atomic);
6607 SET_CXOBJCPROP_ATTR(weak);
6608 SET_CXOBJCPROP_ATTR(strong);
6609 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6610#undef SET_CXOBJCPROP_ATTR
6611
6612 return Result;
6613}
6614
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006615unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6616 if (!clang_isDeclaration(C.kind))
6617 return CXObjCDeclQualifier_None;
6618
6619 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6620 const Decl *D = getCursorDecl(C);
6621 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6622 QT = MD->getObjCDeclQualifier();
6623 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6624 QT = PD->getObjCDeclQualifier();
6625 if (QT == Decl::OBJC_TQ_None)
6626 return CXObjCDeclQualifier_None;
6627
6628 unsigned Result = CXObjCDeclQualifier_None;
6629 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6630 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6631 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6632 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6633 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6634 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6635
6636 return Result;
6637}
6638
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006639unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6640 if (!clang_isDeclaration(C.kind))
6641 return 0;
6642
6643 const Decl *D = getCursorDecl(C);
6644 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6645 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6646 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6647 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6648
6649 return 0;
6650}
6651
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006652unsigned clang_Cursor_isVariadic(CXCursor C) {
6653 if (!clang_isDeclaration(C.kind))
6654 return 0;
6655
6656 const Decl *D = getCursorDecl(C);
6657 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6658 return FD->isVariadic();
6659 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6660 return MD->isVariadic();
6661
6662 return 0;
6663}
6664
Guy Benyei11169dd2012-12-18 14:30:41 +00006665CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6666 if (!clang_isDeclaration(C.kind))
6667 return clang_getNullRange();
6668
6669 const Decl *D = getCursorDecl(C);
6670 ASTContext &Context = getCursorContext(C);
6671 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6672 if (!RC)
6673 return clang_getNullRange();
6674
6675 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6676}
6677
6678CXString clang_Cursor_getRawCommentText(CXCursor C) {
6679 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006680 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006681
6682 const Decl *D = getCursorDecl(C);
6683 ASTContext &Context = getCursorContext(C);
6684 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6685 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6686 StringRef();
6687
6688 // Don't duplicate the string because RawText points directly into source
6689 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006690 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006691}
6692
6693CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6694 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006695 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006696
6697 const Decl *D = getCursorDecl(C);
6698 const ASTContext &Context = getCursorContext(C);
6699 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6700
6701 if (RC) {
6702 StringRef BriefText = RC->getBriefText(Context);
6703
6704 // Don't duplicate the string because RawComment ensures that this memory
6705 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006706 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006707 }
6708
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006709 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006710}
6711
Guy Benyei11169dd2012-12-18 14:30:41 +00006712CXModule clang_Cursor_getModule(CXCursor C) {
6713 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006714 if (const ImportDecl *ImportD =
6715 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006716 return ImportD->getImportedModule();
6717 }
6718
Craig Topper69186e72014-06-08 08:38:04 +00006719 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006720}
6721
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006722CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6723 if (isNotUsableTU(TU)) {
6724 LOG_BAD_TU(TU);
6725 return nullptr;
6726 }
6727 if (!File)
6728 return nullptr;
6729 FileEntry *FE = static_cast<FileEntry *>(File);
6730
6731 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6732 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6733 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6734
Richard Smithfeb54b62014-10-23 02:01:19 +00006735 return Header.getModule();
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006736}
6737
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006738CXFile clang_Module_getASTFile(CXModule CXMod) {
6739 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006740 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006741 Module *Mod = static_cast<Module*>(CXMod);
6742 return const_cast<FileEntry *>(Mod->getASTFile());
6743}
6744
Guy Benyei11169dd2012-12-18 14:30:41 +00006745CXModule clang_Module_getParent(CXModule CXMod) {
6746 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006747 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006748 Module *Mod = static_cast<Module*>(CXMod);
6749 return Mod->Parent;
6750}
6751
6752CXString clang_Module_getName(CXModule CXMod) {
6753 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006754 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006755 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006756 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006757}
6758
6759CXString clang_Module_getFullName(CXModule CXMod) {
6760 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006761 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006762 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006763 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006764}
6765
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006766int clang_Module_isSystem(CXModule CXMod) {
6767 if (!CXMod)
6768 return 0;
6769 Module *Mod = static_cast<Module*>(CXMod);
6770 return Mod->IsSystem;
6771}
6772
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006773unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6774 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006775 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006776 LOG_BAD_TU(TU);
6777 return 0;
6778 }
6779 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006780 return 0;
6781 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006782 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6783 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6784 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006785}
6786
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006787CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6788 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006789 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006790 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006791 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006792 }
6793 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006794 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006795 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006796 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006797
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006798 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6799 if (Index < TopHeaders.size())
6800 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006801
Craig Topper69186e72014-06-08 08:38:04 +00006802 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006803}
6804
6805} // end: extern "C"
6806
6807//===----------------------------------------------------------------------===//
6808// C++ AST instrospection.
6809//===----------------------------------------------------------------------===//
6810
6811extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006812unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6813 if (!clang_isDeclaration(C.kind))
6814 return 0;
6815
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006816 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006817 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006818 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006819 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6820}
6821
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006822unsigned clang_CXXMethod_isConst(CXCursor C) {
6823 if (!clang_isDeclaration(C.kind))
6824 return 0;
6825
6826 const Decl *D = cxcursor::getCursorDecl(C);
6827 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006828 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006829 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6830}
6831
Guy Benyei11169dd2012-12-18 14:30:41 +00006832unsigned clang_CXXMethod_isStatic(CXCursor C) {
6833 if (!clang_isDeclaration(C.kind))
6834 return 0;
6835
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006836 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006837 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006838 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006839 return (Method && Method->isStatic()) ? 1 : 0;
6840}
6841
6842unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6843 if (!clang_isDeclaration(C.kind))
6844 return 0;
6845
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006846 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006847 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006848 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006849 return (Method && Method->isVirtual()) ? 1 : 0;
6850}
6851} // end: extern "C"
6852
6853//===----------------------------------------------------------------------===//
6854// Attribute introspection.
6855//===----------------------------------------------------------------------===//
6856
6857extern "C" {
6858CXType clang_getIBOutletCollectionType(CXCursor C) {
6859 if (C.kind != CXCursor_IBOutletCollectionAttr)
6860 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6861
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006862 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006863 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6864
6865 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6866}
6867} // end: extern "C"
6868
6869//===----------------------------------------------------------------------===//
6870// Inspecting memory usage.
6871//===----------------------------------------------------------------------===//
6872
6873typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6874
6875static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6876 enum CXTUResourceUsageKind k,
6877 unsigned long amount) {
6878 CXTUResourceUsageEntry entry = { k, amount };
6879 entries.push_back(entry);
6880}
6881
6882extern "C" {
6883
6884const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6885 const char *str = "";
6886 switch (kind) {
6887 case CXTUResourceUsage_AST:
6888 str = "ASTContext: expressions, declarations, and types";
6889 break;
6890 case CXTUResourceUsage_Identifiers:
6891 str = "ASTContext: identifiers";
6892 break;
6893 case CXTUResourceUsage_Selectors:
6894 str = "ASTContext: selectors";
6895 break;
6896 case CXTUResourceUsage_GlobalCompletionResults:
6897 str = "Code completion: cached global results";
6898 break;
6899 case CXTUResourceUsage_SourceManagerContentCache:
6900 str = "SourceManager: content cache allocator";
6901 break;
6902 case CXTUResourceUsage_AST_SideTables:
6903 str = "ASTContext: side tables";
6904 break;
6905 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6906 str = "SourceManager: malloc'ed memory buffers";
6907 break;
6908 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6909 str = "SourceManager: mmap'ed memory buffers";
6910 break;
6911 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6912 str = "ExternalASTSource: malloc'ed memory buffers";
6913 break;
6914 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6915 str = "ExternalASTSource: mmap'ed memory buffers";
6916 break;
6917 case CXTUResourceUsage_Preprocessor:
6918 str = "Preprocessor: malloc'ed memory";
6919 break;
6920 case CXTUResourceUsage_PreprocessingRecord:
6921 str = "Preprocessor: PreprocessingRecord";
6922 break;
6923 case CXTUResourceUsage_SourceManager_DataStructures:
6924 str = "SourceManager: data structures and tables";
6925 break;
6926 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6927 str = "Preprocessor: header search tables";
6928 break;
6929 }
6930 return str;
6931}
6932
6933CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006934 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006935 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006936 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00006937 return usage;
6938 }
6939
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006940 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006941 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006942 ASTContext &astContext = astUnit->getASTContext();
6943
6944 // How much memory is used by AST nodes and types?
6945 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6946 (unsigned long) astContext.getASTAllocatedMemory());
6947
6948 // How much memory is used by identifiers?
6949 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6950 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6951
6952 // How much memory is used for selectors?
6953 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6954 (unsigned long) astContext.Selectors.getTotalMemory());
6955
6956 // How much memory is used by ASTContext's side tables?
6957 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6958 (unsigned long) astContext.getSideTableAllocatedMemory());
6959
6960 // How much memory is used for caching global code completion results?
6961 unsigned long completionBytes = 0;
6962 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00006963 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006964 completionBytes = completionAllocator->getTotalMemory();
6965 }
6966 createCXTUResourceUsageEntry(*entries,
6967 CXTUResourceUsage_GlobalCompletionResults,
6968 completionBytes);
6969
6970 // How much memory is being used by SourceManager's content cache?
6971 createCXTUResourceUsageEntry(*entries,
6972 CXTUResourceUsage_SourceManagerContentCache,
6973 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6974
6975 // How much memory is being used by the MemoryBuffer's in SourceManager?
6976 const SourceManager::MemoryBufferSizes &srcBufs =
6977 astUnit->getSourceManager().getMemoryBufferSizes();
6978
6979 createCXTUResourceUsageEntry(*entries,
6980 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6981 (unsigned long) srcBufs.malloc_bytes);
6982 createCXTUResourceUsageEntry(*entries,
6983 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6984 (unsigned long) srcBufs.mmap_bytes);
6985 createCXTUResourceUsageEntry(*entries,
6986 CXTUResourceUsage_SourceManager_DataStructures,
6987 (unsigned long) astContext.getSourceManager()
6988 .getDataStructureSizes());
6989
6990 // How much memory is being used by the ExternalASTSource?
6991 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6992 const ExternalASTSource::MemoryBufferSizes &sizes =
6993 esrc->getMemoryBufferSizes();
6994
6995 createCXTUResourceUsageEntry(*entries,
6996 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6997 (unsigned long) sizes.malloc_bytes);
6998 createCXTUResourceUsageEntry(*entries,
6999 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
7000 (unsigned long) sizes.mmap_bytes);
7001 }
7002
7003 // How much memory is being used by the Preprocessor?
7004 Preprocessor &pp = astUnit->getPreprocessor();
7005 createCXTUResourceUsageEntry(*entries,
7006 CXTUResourceUsage_Preprocessor,
7007 pp.getTotalMemory());
7008
7009 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
7010 createCXTUResourceUsageEntry(*entries,
7011 CXTUResourceUsage_PreprocessingRecord,
7012 pRec->getTotalMemory());
7013 }
7014
7015 createCXTUResourceUsageEntry(*entries,
7016 CXTUResourceUsage_Preprocessor_HeaderSearch,
7017 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00007018
Guy Benyei11169dd2012-12-18 14:30:41 +00007019 CXTUResourceUsage usage = { (void*) entries.get(),
7020 (unsigned) entries->size(),
Alexander Kornienko6ee521c2015-01-23 15:36:10 +00007021 !entries->empty() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00007022 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00007023 return usage;
7024}
7025
7026void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
7027 if (usage.data)
7028 delete (MemUsageEntries*) usage.data;
7029}
7030
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007031CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
7032 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007033 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00007034 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007035
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007036 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007037 LOG_BAD_TU(TU);
7038 return skipped;
7039 }
7040
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007041 if (!file)
7042 return skipped;
7043
7044 ASTUnit *astUnit = cxtu::getASTUnit(TU);
7045 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
7046 if (!ppRec)
7047 return skipped;
7048
7049 ASTContext &Ctx = astUnit->getASTContext();
7050 SourceManager &sm = Ctx.getSourceManager();
7051 FileEntry *fileEntry = static_cast<FileEntry *>(file);
7052 FileID wantedFileID = sm.translateFile(fileEntry);
7053
7054 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
7055 std::vector<SourceRange> wantedRanges;
7056 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
7057 i != ei; ++i) {
7058 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
7059 wantedRanges.push_back(*i);
7060 }
7061
7062 skipped->count = wantedRanges.size();
7063 skipped->ranges = new CXSourceRange[skipped->count];
7064 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
7065 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
7066
7067 return skipped;
7068}
7069
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007070void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
7071 if (ranges) {
7072 delete[] ranges->ranges;
7073 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007074 }
7075}
7076
Guy Benyei11169dd2012-12-18 14:30:41 +00007077} // end extern "C"
7078
7079void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
7080 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
7081 for (unsigned I = 0; I != Usage.numEntries; ++I)
7082 fprintf(stderr, " %s: %lu\n",
7083 clang_getTUResourceUsageName(Usage.entries[I].kind),
7084 Usage.entries[I].amount);
7085
7086 clang_disposeCXTUResourceUsage(Usage);
7087}
7088
7089//===----------------------------------------------------------------------===//
7090// Misc. utility functions.
7091//===----------------------------------------------------------------------===//
7092
7093/// Default to using an 8 MB stack size on "safety" threads.
7094static unsigned SafetyStackThreadSize = 8 << 20;
7095
7096namespace clang {
7097
7098bool RunSafely(llvm::CrashRecoveryContext &CRC,
7099 void (*Fn)(void*), void *UserData,
7100 unsigned Size) {
7101 if (!Size)
7102 Size = GetSafetyThreadStackSize();
7103 if (Size)
7104 return CRC.RunSafelyOnThread(Fn, UserData, Size);
7105 return CRC.RunSafely(Fn, UserData);
7106}
7107
7108unsigned GetSafetyThreadStackSize() {
7109 return SafetyStackThreadSize;
7110}
7111
7112void SetSafetyThreadStackSize(unsigned Value) {
7113 SafetyStackThreadSize = Value;
7114}
7115
7116}
7117
7118void clang::setThreadBackgroundPriority() {
7119 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
7120 return;
7121
Alp Toker1a86ad22014-07-06 06:24:00 +00007122#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00007123 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
7124#endif
7125}
7126
7127void cxindex::printDiagsToStderr(ASTUnit *Unit) {
7128 if (!Unit)
7129 return;
7130
7131 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
7132 DEnd = Unit->stored_diag_end();
7133 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00007134 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00007135 CXString Msg = clang_formatDiagnostic(&Diag,
7136 clang_defaultDiagnosticDisplayOptions());
7137 fprintf(stderr, "%s\n", clang_getCString(Msg));
7138 clang_disposeString(Msg);
7139 }
7140#ifdef LLVM_ON_WIN32
7141 // On Windows, force a flush, since there may be multiple copies of
7142 // stderr and stdout in the file system, all with different buffers
7143 // but writing to the same device.
7144 fflush(stderr);
7145#endif
7146}
7147
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007148MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
7149 SourceLocation MacroDefLoc,
7150 CXTranslationUnit TU){
7151 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007152 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007153 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007154 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007155
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007156 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007157 Preprocessor &PP = Unit->getPreprocessor();
Richard Smith20e883e2015-04-29 23:20:19 +00007158 MacroDirective *MD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007159 if (MD) {
7160 for (MacroDirective::DefInfo
7161 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
7162 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
7163 return Def.getMacroInfo();
7164 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007165 }
7166
Craig Topper69186e72014-06-08 08:38:04 +00007167 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007168}
7169
Richard Smith66a81862015-05-04 02:25:31 +00007170const MacroInfo *cxindex::getMacroInfo(const MacroDefinitionRecord *MacroDef,
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007171 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007172 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007173 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007174 const IdentifierInfo *II = MacroDef->getName();
7175 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00007176 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007177
7178 return getMacroInfo(*II, MacroDef->getLocation(), TU);
7179}
7180
Richard Smith66a81862015-05-04 02:25:31 +00007181MacroDefinitionRecord *
7182cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, const Token &Tok,
7183 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007184 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007185 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007186 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00007187 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007188
7189 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007190 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007191 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
7192 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007193 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007194
7195 // Check that the token is inside the definition and not its argument list.
7196 SourceManager &SM = Unit->getSourceManager();
7197 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00007198 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007199 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00007200 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007201
7202 Preprocessor &PP = Unit->getPreprocessor();
7203 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
7204 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00007205 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007206
Alp Toker2d57cea2014-05-17 04:53:25 +00007207 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007208 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007209 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007210
7211 // Check that the identifier is not one of the macro arguments.
7212 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00007213 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007214
Richard Smith20e883e2015-04-29 23:20:19 +00007215 MacroDirective *InnerMD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007216 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00007217 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007218
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007219 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007220}
7221
Richard Smith66a81862015-05-04 02:25:31 +00007222MacroDefinitionRecord *
7223cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, SourceLocation Loc,
7224 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007225 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007226 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007227
7228 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007229 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007230 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007231 Preprocessor &PP = Unit->getPreprocessor();
7232 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00007233 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007234 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7235 Token Tok;
7236 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00007237 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007238
7239 return checkForMacroInMacroDefinition(MI, Tok, TU);
7240}
7241
Guy Benyei11169dd2012-12-18 14:30:41 +00007242extern "C" {
7243
7244CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007245 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00007246}
7247
7248} // end: extern "C"
7249
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007250Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7251 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007252 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007253 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007254 if (Unit->isMainFileAST())
7255 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007256 return *this;
7257 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007258 } else {
7259 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007260 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007261 return *this;
7262}
7263
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007264Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7265 *this << FE->getName();
7266 return *this;
7267}
7268
7269Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7270 CXString cursorName = clang_getCursorDisplayName(cursor);
7271 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7272 clang_disposeString(cursorName);
7273 return *this;
7274}
7275
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007276Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7277 CXFile File;
7278 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007279 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007280 CXString FileName = clang_getFileName(File);
7281 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7282 clang_disposeString(FileName);
7283 return *this;
7284}
7285
7286Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7287 CXSourceLocation BLoc = clang_getRangeStart(range);
7288 CXSourceLocation ELoc = clang_getRangeEnd(range);
7289
7290 CXFile BFile;
7291 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007292 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007293
7294 CXFile EFile;
7295 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007296 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007297
7298 CXString BFileName = clang_getFileName(BFile);
7299 if (BFile == EFile) {
7300 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7301 BLine, BColumn, ELine, EColumn);
7302 } else {
7303 CXString EFileName = clang_getFileName(EFile);
7304 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7305 BLine, BColumn)
7306 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7307 ELine, EColumn);
7308 clang_disposeString(EFileName);
7309 }
7310 clang_disposeString(BFileName);
7311 return *this;
7312}
7313
7314Logger &cxindex::Logger::operator<<(CXString Str) {
7315 *this << clang_getCString(Str);
7316 return *this;
7317}
7318
7319Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7320 LogOS << Fmt;
7321 return *this;
7322}
7323
Chandler Carruth37ad2582014-06-27 15:14:39 +00007324static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7325
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007326cxindex::Logger::~Logger() {
7327 LogOS.flush();
7328
Chandler Carruth37ad2582014-06-27 15:14:39 +00007329 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007330
7331 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7332
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007333 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007334 OS << "[libclang:" << Name << ':';
7335
Alp Toker1a86ad22014-07-06 06:24:00 +00007336#ifdef USE_DARWIN_THREADS
7337 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007338 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7339 OS << tid << ':';
7340#endif
7341
7342 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7343 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
Yaron Keren09fb7c62015-03-10 07:33:23 +00007344 OS << Msg << '\n';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007345
7346 if (Trace) {
Zachary Turner1fe2a8d2015-03-05 19:15:09 +00007347 llvm::sys::PrintStackTrace(OS);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007348 OS << "--------------------------------------------------\n";
7349 }
7350}