blob: 2216ec61afa74e67a3fcfe0c112cf2502486ec6a [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(
Adrian Prantlbb165fb2015-06-20 18:53:08 +00002892 ast_filename, CXXIdx->getPCHContainerOperations(), Diags, FileSystemOpts,
2893 CXXIdx->getOnlyLocalDecls(), None,
David Blaikie6f7382d2014-08-10 19:08:04 +00002894 /*CaptureDiagnostics=*/true,
2895 /*AllowPCHWithCompilerErrors=*/true,
2896 /*UserFilesAreVolatile=*/true);
2897 *out_TU = MakeCXTranslationUnit(CXXIdx, AU.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002898 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002899}
2900
2901unsigned clang_defaultEditingTranslationUnitOptions() {
2902 return CXTranslationUnit_PrecompiledPreamble |
2903 CXTranslationUnit_CacheCompletionResults;
2904}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002905
Guy Benyei11169dd2012-12-18 14:30:41 +00002906CXTranslationUnit
2907clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2908 const char *source_filename,
2909 int num_command_line_args,
2910 const char * const *command_line_args,
2911 unsigned num_unsaved_files,
2912 struct CXUnsavedFile *unsaved_files) {
2913 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2914 return clang_parseTranslationUnit(CIdx, source_filename,
2915 command_line_args, num_command_line_args,
2916 unsaved_files, num_unsaved_files,
2917 Options);
2918}
2919
2920struct ParseTranslationUnitInfo {
2921 CXIndex CIdx;
2922 const char *source_filename;
2923 const char *const *command_line_args;
2924 int num_command_line_args;
Alp Toker9d85b182014-07-07 01:23:14 +00002925 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00002926 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002927 CXTranslationUnit *out_TU;
Alp Toker5c532982014-07-07 22:42:03 +00002928 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002929};
2930static void clang_parseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00002931 const ParseTranslationUnitInfo *PTUI =
2932 static_cast<ParseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00002933 CXIndex CIdx = PTUI->CIdx;
2934 const char *source_filename = PTUI->source_filename;
2935 const char * const *command_line_args = PTUI->command_line_args;
2936 int num_command_line_args = PTUI->num_command_line_args;
Guy Benyei11169dd2012-12-18 14:30:41 +00002937 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002938 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002939
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002940 // Set up the initial return values.
2941 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002942 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002943
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002944 // Check arguments.
Alp Toker9d85b182014-07-07 01:23:14 +00002945 if (!CIdx || !out_TU) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002946 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002947 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002948 }
2949
Guy Benyei11169dd2012-12-18 14:30:41 +00002950 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2951
2952 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2953 setThreadBackgroundPriority();
2954
2955 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2956 // FIXME: Add a flag for modules.
2957 TranslationUnitKind TUKind
2958 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002959 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002960 = options & CXTranslationUnit_CacheCompletionResults;
2961 bool IncludeBriefCommentsInCodeCompletion
2962 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2963 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2964 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2965
2966 // Configure the diagnostics.
2967 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002968 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002969
2970 // Recover resources if we crash before exiting this function.
2971 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2972 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00002973 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00002974
Ahmed Charlesb8984322014-03-07 20:03:18 +00002975 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
2976 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002977
2978 // Recover resources if we crash before exiting this function.
2979 llvm::CrashRecoveryContextCleanupRegistrar<
2980 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2981
Alp Toker9d85b182014-07-07 01:23:14 +00002982 for (auto &UF : PTUI->unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00002983 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00002984 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00002985 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00002986 }
2987
Ahmed Charlesb8984322014-03-07 20:03:18 +00002988 std::unique_ptr<std::vector<const char *>> Args(
2989 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002990
2991 // Recover resources if we crash before exiting this method.
2992 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2993 ArgsCleanup(Args.get());
2994
2995 // Since the Clang C library is primarily used by batch tools dealing with
2996 // (often very broken) source code, where spell-checking can have a
2997 // significant negative impact on performance (particularly when
2998 // precompiled headers are involved), we disable it by default.
2999 // Only do this if we haven't found a spell-checking-related argument.
3000 bool FoundSpellCheckingArgument = false;
3001 for (int I = 0; I != num_command_line_args; ++I) {
3002 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
3003 strcmp(command_line_args[I], "-fspell-checking") == 0) {
3004 FoundSpellCheckingArgument = true;
3005 break;
3006 }
3007 }
3008 if (!FoundSpellCheckingArgument)
3009 Args->push_back("-fno-spell-checking");
3010
3011 Args->insert(Args->end(), command_line_args,
3012 command_line_args + num_command_line_args);
3013
3014 // The 'source_filename' argument is optional. If the caller does not
3015 // specify it then it is assumed that the source file is specified
3016 // in the actual argument list.
3017 // Put the source file after command_line_args otherwise if '-x' flag is
3018 // present it will be unused.
3019 if (source_filename)
3020 Args->push_back(source_filename);
3021
3022 // Do we need the detailed preprocessing record?
3023 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
3024 Args->push_back("-Xclang");
3025 Args->push_back("-detailed-preprocessing-record");
3026 }
3027
3028 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00003029 std::unique_ptr<ASTUnit> ErrUnit;
3030 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003031 Args->data(), Args->data() + Args->size(),
3032 CXXIdx->getPCHContainerOperations(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00003033 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
3034 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
3035 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
3036 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
3037 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
3038 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00003039
3040 if (NumErrors != Diags->getClient()->getNumErrors()) {
3041 // Make sure to check that 'Unit' is non-NULL.
3042 if (CXXIdx->getDisplayDiagnostics())
3043 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
3044 }
3045
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003046 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
3047 PTUI->result = CXError_ASTReadError;
3048 } else {
Ahmed Charles9a16beb2014-03-07 19:33:25 +00003049 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003050 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
3051 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003052}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003053
3054CXTranslationUnit
3055clang_parseTranslationUnit(CXIndex CIdx,
3056 const char *source_filename,
3057 const char *const *command_line_args,
3058 int num_command_line_args,
3059 struct CXUnsavedFile *unsaved_files,
3060 unsigned num_unsaved_files,
3061 unsigned options) {
3062 CXTranslationUnit TU;
3063 enum CXErrorCode Result = clang_parseTranslationUnit2(
3064 CIdx, source_filename, command_line_args, num_command_line_args,
3065 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00003066 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003067 assert((TU && Result == CXError_Success) ||
3068 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003069 return TU;
3070}
3071
3072enum CXErrorCode clang_parseTranslationUnit2(
3073 CXIndex CIdx,
3074 const char *source_filename,
3075 const char *const *command_line_args,
3076 int num_command_line_args,
3077 struct CXUnsavedFile *unsaved_files,
3078 unsigned num_unsaved_files,
3079 unsigned options,
3080 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003081 LOG_FUNC_SECTION {
3082 *Log << source_filename << ": ";
3083 for (int i = 0; i != num_command_line_args; ++i)
3084 *Log << command_line_args[i] << " ";
3085 }
3086
Alp Toker9d85b182014-07-07 01:23:14 +00003087 if (num_unsaved_files && !unsaved_files)
3088 return CXError_InvalidArguments;
3089
Alp Toker5c532982014-07-07 22:42:03 +00003090 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00003091 ParseTranslationUnitInfo PTUI = {
3092 CIdx,
3093 source_filename,
3094 command_line_args,
3095 num_command_line_args,
3096 llvm::makeArrayRef(unsaved_files, num_unsaved_files),
3097 options,
3098 out_TU,
Alp Toker5c532982014-07-07 22:42:03 +00003099 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00003100 llvm::CrashRecoveryContext CRC;
3101
3102 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
3103 fprintf(stderr, "libclang: crash detected during parsing: {\n");
3104 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3105 fprintf(stderr, " 'command_line_args' : [");
3106 for (int i = 0; i != num_command_line_args; ++i) {
3107 if (i)
3108 fprintf(stderr, ", ");
3109 fprintf(stderr, "'%s'", command_line_args[i]);
3110 }
3111 fprintf(stderr, "],\n");
3112 fprintf(stderr, " 'unsaved_files' : [");
3113 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3114 if (i)
3115 fprintf(stderr, ", ");
3116 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3117 unsaved_files[i].Length);
3118 }
3119 fprintf(stderr, "],\n");
3120 fprintf(stderr, " 'options' : %d,\n", options);
3121 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003122
3123 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003124 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003125 if (CXTranslationUnit *TU = PTUI.out_TU)
3126 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003127 }
Alp Toker5c532982014-07-07 22:42:03 +00003128
3129 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003130}
3131
3132unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
3133 return CXSaveTranslationUnit_None;
3134}
3135
3136namespace {
3137
3138struct SaveTranslationUnitInfo {
3139 CXTranslationUnit TU;
3140 const char *FileName;
3141 unsigned options;
3142 CXSaveError result;
3143};
3144
3145}
3146
3147static void clang_saveTranslationUnit_Impl(void *UserData) {
3148 SaveTranslationUnitInfo *STUI =
3149 static_cast<SaveTranslationUnitInfo*>(UserData);
3150
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003151 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003152 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3153 setThreadBackgroundPriority();
3154
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003155 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00003156 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
3157}
3158
3159int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3160 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003161 LOG_FUNC_SECTION {
3162 *Log << TU << ' ' << FileName;
3163 }
3164
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003165 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003166 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003167 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003168 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003169
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003170 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003171 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3172 if (!CXXUnit->hasSema())
3173 return CXSaveError_InvalidTU;
3174
3175 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
3176
3177 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3178 getenv("LIBCLANG_NOTHREADS")) {
3179 clang_saveTranslationUnit_Impl(&STUI);
3180
3181 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3182 PrintLibclangResourceUsage(TU);
3183
3184 return STUI.result;
3185 }
3186
3187 // We have an AST that has invalid nodes due to compiler errors.
3188 // Use a crash recovery thread for protection.
3189
3190 llvm::CrashRecoveryContext CRC;
3191
3192 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
3193 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3194 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3195 fprintf(stderr, " 'options' : %d,\n", options);
3196 fprintf(stderr, "}\n");
3197
3198 return CXSaveError_Unknown;
3199
3200 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3201 PrintLibclangResourceUsage(TU);
3202 }
3203
3204 return STUI.result;
3205}
3206
3207void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3208 if (CTUnit) {
3209 // If the translation unit has been marked as unsafe to free, just discard
3210 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003211 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3212 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003213 return;
3214
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003215 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003216 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003217 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3218 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003219 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003220 delete CTUnit;
3221 }
3222}
3223
3224unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3225 return CXReparse_None;
3226}
3227
3228struct ReparseTranslationUnitInfo {
3229 CXTranslationUnit TU;
Alp Toker9d85b182014-07-07 01:23:14 +00003230 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00003231 unsigned options;
Alp Toker5c532982014-07-07 22:42:03 +00003232 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003233};
3234
3235static void clang_reparseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00003236 const ReparseTranslationUnitInfo *RTUI =
3237 static_cast<ReparseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00003238 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003239 unsigned options = RTUI->options;
3240 (void) options;
3241
3242 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003243 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003244 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003245 RTUI->result = CXError_InvalidArguments;
3246 return;
3247 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003248
3249 // Reset the associated diagnostics.
3250 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003251 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003252
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003253 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003254 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3255 setThreadBackgroundPriority();
3256
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003257 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003258 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003259
3260 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3261 new std::vector<ASTUnit::RemappedFile>());
3262
Guy Benyei11169dd2012-12-18 14:30:41 +00003263 // Recover resources if we crash before exiting this function.
3264 llvm::CrashRecoveryContextCleanupRegistrar<
3265 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003266
3267 for (auto &UF : RTUI->unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003268 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003269 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003270 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003271 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003272
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003273 if (!CXXUnit->Reparse(CXXIdx->getPCHContainerOperations(),
3274 *RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003275 RTUI->result = CXError_Success;
3276 else if (isASTReadError(CXXUnit))
3277 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003278}
3279
3280int clang_reparseTranslationUnit(CXTranslationUnit TU,
3281 unsigned num_unsaved_files,
3282 struct CXUnsavedFile *unsaved_files,
3283 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003284 LOG_FUNC_SECTION {
3285 *Log << TU;
3286 }
3287
Alp Toker9d85b182014-07-07 01:23:14 +00003288 if (num_unsaved_files && !unsaved_files)
3289 return CXError_InvalidArguments;
3290
Alp Toker5c532982014-07-07 22:42:03 +00003291 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00003292 ReparseTranslationUnitInfo RTUI = {
3293 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options,
Alp Toker5c532982014-07-07 22:42:03 +00003294 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00003295
3296 if (getenv("LIBCLANG_NOTHREADS")) {
3297 clang_reparseTranslationUnit_Impl(&RTUI);
Alp Toker5c532982014-07-07 22:42:03 +00003298 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003299 }
3300
3301 llvm::CrashRecoveryContext CRC;
3302
3303 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3304 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003305 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003306 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003307 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3308 PrintLibclangResourceUsage(TU);
3309
Alp Toker5c532982014-07-07 22:42:03 +00003310 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003311}
3312
3313
3314CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003315 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003316 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003317 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003318 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003319
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003320 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003321 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003322}
3323
3324CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003325 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003326 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003327 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003328 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003329
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003330 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003331 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3332}
3333
3334} // end: extern "C"
3335
3336//===----------------------------------------------------------------------===//
3337// CXFile Operations.
3338//===----------------------------------------------------------------------===//
3339
3340extern "C" {
3341CXString clang_getFileName(CXFile SFile) {
3342 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003343 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003344
3345 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003346 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003347}
3348
3349time_t clang_getFileTime(CXFile SFile) {
3350 if (!SFile)
3351 return 0;
3352
3353 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3354 return FEnt->getModificationTime();
3355}
3356
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003357CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003358 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003359 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003360 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003361 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003362
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003363 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003364
3365 FileManager &FMgr = CXXUnit->getFileManager();
3366 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3367}
3368
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003369unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3370 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003371 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003372 LOG_BAD_TU(TU);
3373 return 0;
3374 }
3375
3376 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003377 return 0;
3378
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003379 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003380 FileEntry *FEnt = static_cast<FileEntry *>(file);
3381 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3382 .isFileMultipleIncludeGuarded(FEnt);
3383}
3384
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003385int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3386 if (!file || !outID)
3387 return 1;
3388
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003389 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003390 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3391 outID->data[0] = ID.getDevice();
3392 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003393 outID->data[2] = FEnt->getModificationTime();
3394 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003395}
3396
Argyrios Kyrtzidisac3997e2014-08-16 00:26:19 +00003397int clang_File_isEqual(CXFile file1, CXFile file2) {
3398 if (file1 == file2)
3399 return true;
3400
3401 if (!file1 || !file2)
3402 return false;
3403
3404 FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
3405 FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
3406 return FEnt1->getUniqueID() == FEnt2->getUniqueID();
3407}
3408
Guy Benyei11169dd2012-12-18 14:30:41 +00003409} // end: extern "C"
3410
3411//===----------------------------------------------------------------------===//
3412// CXCursor Operations.
3413//===----------------------------------------------------------------------===//
3414
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003415static const Decl *getDeclFromExpr(const Stmt *E) {
3416 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003417 return getDeclFromExpr(CE->getSubExpr());
3418
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003419 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003420 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003421 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003422 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003423 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003424 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003425 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003426 if (PRE->isExplicitProperty())
3427 return PRE->getExplicitProperty();
3428 // It could be messaging both getter and setter as in:
3429 // ++myobj.myprop;
3430 // in which case prefer to associate the setter since it is less obvious
3431 // from inspecting the source that the setter is going to get called.
3432 if (PRE->isMessagingSetter())
3433 return PRE->getImplicitPropertySetter();
3434 return PRE->getImplicitPropertyGetter();
3435 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003436 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003437 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003438 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003439 if (Expr *Src = OVE->getSourceExpr())
3440 return getDeclFromExpr(Src);
3441
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003442 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003443 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003444 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003445 if (!CE->isElidable())
3446 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003447 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003448 return OME->getMethodDecl();
3449
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003450 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003451 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003452 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003453 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3454 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003455 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003456 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3457 isa<ParmVarDecl>(SizeOfPack->getPack()))
3458 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003459
3460 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003461}
3462
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003463static SourceLocation getLocationFromExpr(const Expr *E) {
3464 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003465 return getLocationFromExpr(CE->getSubExpr());
3466
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003467 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003468 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003469 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003470 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003471 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003472 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003473 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003474 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003475 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003476 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003477 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003478 return PropRef->getLocation();
3479
3480 return E->getLocStart();
3481}
3482
3483extern "C" {
3484
3485unsigned clang_visitChildren(CXCursor parent,
3486 CXCursorVisitor visitor,
3487 CXClientData client_data) {
3488 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3489 /*VisitPreprocessorLast=*/false);
3490 return CursorVis.VisitChildren(parent);
3491}
3492
3493#ifndef __has_feature
3494#define __has_feature(x) 0
3495#endif
3496#if __has_feature(blocks)
3497typedef enum CXChildVisitResult
3498 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3499
3500static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3501 CXClientData client_data) {
3502 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3503 return block(cursor, parent);
3504}
3505#else
3506// If we are compiled with a compiler that doesn't have native blocks support,
3507// define and call the block manually, so the
3508typedef struct _CXChildVisitResult
3509{
3510 void *isa;
3511 int flags;
3512 int reserved;
3513 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3514 CXCursor);
3515} *CXCursorVisitorBlock;
3516
3517static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3518 CXClientData client_data) {
3519 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3520 return block->invoke(block, cursor, parent);
3521}
3522#endif
3523
3524
3525unsigned clang_visitChildrenWithBlock(CXCursor parent,
3526 CXCursorVisitorBlock block) {
3527 return clang_visitChildren(parent, visitWithBlock, block);
3528}
3529
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003530static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003531 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003532 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003533
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003534 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003535 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003536 if (const ObjCPropertyImplDecl *PropImpl =
3537 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003538 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003539 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003540
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003541 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003542 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003543 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003544
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003545 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003546 }
3547
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003548 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003549 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003550
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003551 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003552 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3553 // and returns different names. NamedDecl returns the class name and
3554 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003555 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003556
3557 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003558 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003559
3560 SmallString<1024> S;
3561 llvm::raw_svector_ostream os(S);
3562 ND->printName(os);
3563
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003564 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003565}
3566
3567CXString clang_getCursorSpelling(CXCursor C) {
3568 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003569 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003570
3571 if (clang_isReference(C.kind)) {
3572 switch (C.kind) {
3573 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003574 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003575 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003576 }
3577 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003578 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003579 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003580 }
3581 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003582 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003583 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003584 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003585 }
3586 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003587 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003588 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003589 }
3590 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003591 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003592 assert(Type && "Missing type decl");
3593
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003594 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003595 getAsString());
3596 }
3597 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003598 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003599 assert(Template && "Missing template decl");
3600
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003601 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003602 }
3603
3604 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003605 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003606 assert(NS && "Missing namespace decl");
3607
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003608 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003609 }
3610
3611 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003612 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003613 assert(Field && "Missing member decl");
3614
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003615 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003616 }
3617
3618 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003619 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003620 assert(Label && "Missing label");
3621
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003622 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003623 }
3624
3625 case CXCursor_OverloadedDeclRef: {
3626 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003627 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3628 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003629 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003630 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003631 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003632 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003633 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003634 OverloadedTemplateStorage *Ovl
3635 = Storage.get<OverloadedTemplateStorage*>();
3636 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003637 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003638 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003639 }
3640
3641 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003642 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003643 assert(Var && "Missing variable decl");
3644
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003645 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003646 }
3647
3648 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003649 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003650 }
3651 }
3652
3653 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003654 const Expr *E = getCursorExpr(C);
3655
3656 if (C.kind == CXCursor_ObjCStringLiteral ||
3657 C.kind == CXCursor_StringLiteral) {
3658 const StringLiteral *SLit;
3659 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3660 SLit = OSL->getString();
3661 } else {
3662 SLit = cast<StringLiteral>(E);
3663 }
3664 SmallString<256> Buf;
3665 llvm::raw_svector_ostream OS(Buf);
3666 SLit->outputString(OS);
3667 return cxstring::createDup(OS.str());
3668 }
3669
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003670 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003671 if (D)
3672 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003673 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003674 }
3675
3676 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003677 const Stmt *S = getCursorStmt(C);
3678 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003679 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003680
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003681 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003682 }
3683
3684 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003685 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003686 ->getNameStart());
3687
3688 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003689 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003690 ->getNameStart());
3691
3692 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003693 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003694
3695 if (clang_isDeclaration(C.kind))
3696 return getDeclSpelling(getCursorDecl(C));
3697
3698 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003699 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003700 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003701 }
3702
3703 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003704 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003705 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003706 }
3707
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003708 if (C.kind == CXCursor_PackedAttr) {
3709 return cxstring::createRef("packed");
3710 }
3711
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003712 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003713}
3714
3715CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3716 unsigned pieceIndex,
3717 unsigned options) {
3718 if (clang_Cursor_isNull(C))
3719 return clang_getNullRange();
3720
3721 ASTContext &Ctx = getCursorContext(C);
3722
3723 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003724 const Stmt *S = getCursorStmt(C);
3725 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003726 if (pieceIndex > 0)
3727 return clang_getNullRange();
3728 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3729 }
3730
3731 return clang_getNullRange();
3732 }
3733
3734 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003735 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003736 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3737 if (pieceIndex >= ME->getNumSelectorLocs())
3738 return clang_getNullRange();
3739 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3740 }
3741 }
3742
3743 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3744 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003745 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003746 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3747 if (pieceIndex >= MD->getNumSelectorLocs())
3748 return clang_getNullRange();
3749 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3750 }
3751 }
3752
3753 if (C.kind == CXCursor_ObjCCategoryDecl ||
3754 C.kind == CXCursor_ObjCCategoryImplDecl) {
3755 if (pieceIndex > 0)
3756 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003757 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003758 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3759 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003760 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003761 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3762 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3763 }
3764
3765 if (C.kind == CXCursor_ModuleImportDecl) {
3766 if (pieceIndex > 0)
3767 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003768 if (const ImportDecl *ImportD =
3769 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003770 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3771 if (!Locs.empty())
3772 return cxloc::translateSourceRange(Ctx,
3773 SourceRange(Locs.front(), Locs.back()));
3774 }
3775 return clang_getNullRange();
3776 }
3777
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00003778 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
3779 C.kind == CXCursor_ConversionFunction) {
3780 if (pieceIndex > 0)
3781 return clang_getNullRange();
3782 if (const FunctionDecl *FD =
3783 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
3784 DeclarationNameInfo FunctionName = FD->getNameInfo();
3785 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
3786 }
3787 return clang_getNullRange();
3788 }
3789
Guy Benyei11169dd2012-12-18 14:30:41 +00003790 // FIXME: A CXCursor_InclusionDirective should give the location of the
3791 // filename, but we don't keep track of this.
3792
3793 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3794 // but we don't keep track of this.
3795
3796 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3797 // but we don't keep track of this.
3798
3799 // Default handling, give the location of the cursor.
3800
3801 if (pieceIndex > 0)
3802 return clang_getNullRange();
3803
3804 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3805 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3806 return cxloc::translateSourceRange(Ctx, Loc);
3807}
3808
Eli Bendersky44a206f2014-07-31 18:04:56 +00003809CXString clang_Cursor_getMangling(CXCursor C) {
3810 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
3811 return cxstring::createEmpty();
3812
Eli Bendersky44a206f2014-07-31 18:04:56 +00003813 // Mangling only works for functions and variables.
Eli Bendersky79759592014-08-01 15:01:10 +00003814 const Decl *D = getCursorDecl(C);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003815 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
3816 return cxstring::createEmpty();
3817
Eli Bendersky79759592014-08-01 15:01:10 +00003818 // First apply frontend mangling.
Eli Bendersky44a206f2014-07-31 18:04:56 +00003819 const NamedDecl *ND = cast<NamedDecl>(D);
Eli Bendersky79759592014-08-01 15:01:10 +00003820 ASTContext &Ctx = ND->getASTContext();
3821 std::unique_ptr<MangleContext> MC(Ctx.createMangleContext());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003822
Eli Bendersky79759592014-08-01 15:01:10 +00003823 std::string FrontendBuf;
3824 llvm::raw_string_ostream FrontendBufOS(FrontendBuf);
3825 MC->mangleName(ND, FrontendBufOS);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003826
Eli Bendersky79759592014-08-01 15:01:10 +00003827 // Now apply backend mangling.
3828 std::unique_ptr<llvm::DataLayout> DL(
3829 new llvm::DataLayout(Ctx.getTargetInfo().getTargetDescription()));
3830 llvm::Mangler BackendMangler(DL.get());
3831
3832 std::string FinalBuf;
3833 llvm::raw_string_ostream FinalBufOS(FinalBuf);
3834 BackendMangler.getNameWithPrefix(FinalBufOS,
3835 llvm::Twine(FrontendBufOS.str()));
3836
3837 return cxstring::createDup(FinalBufOS.str());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003838}
3839
Guy Benyei11169dd2012-12-18 14:30:41 +00003840CXString clang_getCursorDisplayName(CXCursor C) {
3841 if (!clang_isDeclaration(C.kind))
3842 return clang_getCursorSpelling(C);
3843
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003844 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003845 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003846 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003847
3848 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003849 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003850 D = FunTmpl->getTemplatedDecl();
3851
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003852 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003853 SmallString<64> Str;
3854 llvm::raw_svector_ostream OS(Str);
3855 OS << *Function;
3856 if (Function->getPrimaryTemplate())
3857 OS << "<>";
3858 OS << "(";
3859 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3860 if (I)
3861 OS << ", ";
3862 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3863 }
3864
3865 if (Function->isVariadic()) {
3866 if (Function->getNumParams())
3867 OS << ", ";
3868 OS << "...";
3869 }
3870 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003871 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003872 }
3873
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003874 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003875 SmallString<64> Str;
3876 llvm::raw_svector_ostream OS(Str);
3877 OS << *ClassTemplate;
3878 OS << "<";
3879 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3880 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3881 if (I)
3882 OS << ", ";
3883
3884 NamedDecl *Param = Params->getParam(I);
3885 if (Param->getIdentifier()) {
3886 OS << Param->getIdentifier()->getName();
3887 continue;
3888 }
3889
3890 // There is no parameter name, which makes this tricky. Try to come up
3891 // with something useful that isn't too long.
3892 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3893 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3894 else if (NonTypeTemplateParmDecl *NTTP
3895 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3896 OS << NTTP->getType().getAsString(Policy);
3897 else
3898 OS << "template<...> class";
3899 }
3900
3901 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003902 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003903 }
3904
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003905 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003906 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3907 // If the type was explicitly written, use that.
3908 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003909 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003910
Benjamin Kramer9170e912013-02-22 15:46:01 +00003911 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003912 llvm::raw_svector_ostream OS(Str);
3913 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003914 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003915 ClassSpec->getTemplateArgs().data(),
3916 ClassSpec->getTemplateArgs().size(),
3917 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003918 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003919 }
3920
3921 return clang_getCursorSpelling(C);
3922}
3923
3924CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3925 switch (Kind) {
3926 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003927 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003928 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003929 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003930 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003931 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003932 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003933 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003934 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003935 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003936 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003937 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003938 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003939 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003940 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003941 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003942 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003943 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003944 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003945 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003946 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003947 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003948 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003949 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003950 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003951 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003952 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003953 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003954 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003955 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003956 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003957 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003958 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003959 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003960 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003961 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003962 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003963 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003964 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003965 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003966 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003967 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003968 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003969 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003970 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003971 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003972 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003973 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003974 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003975 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003976 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003977 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003978 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003979 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003980 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003981 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003982 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003983 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003984 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003985 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003986 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003987 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003988 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003989 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003990 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003991 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003992 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003993 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003994 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003995 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003996 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003997 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003998 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003999 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004000 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004001 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004002 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004003 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004004 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004005 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004006 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004007 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004008 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004009 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004010 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004011 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004012 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004013 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004014 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004015 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004016 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004017 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004018 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004019 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004020 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004021 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004022 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004023 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004024 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004025 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004026 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004027 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004028 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004029 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004030 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004031 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004032 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004033 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004034 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004035 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004036 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004037 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004038 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004039 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004040 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004041 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004042 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004043 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004044 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004045 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004046 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004047 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004048 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004049 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004050 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004051 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004052 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004053 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00004054 case CXCursor_ObjCSelfExpr:
4055 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004056 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004057 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004058 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004059 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004060 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004061 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004062 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004063 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004064 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004065 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004066 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004067 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004068 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004069 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004070 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004071 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004072 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004073 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004074 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004075 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004076 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004077 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004078 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004079 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004080 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004081 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004082 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004083 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004084 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004085 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004086 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004087 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004088 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004089 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004090 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004091 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004092 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004093 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004094 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004095 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004096 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004097 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004098 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004099 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004100 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004101 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004102 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004103 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004104 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004105 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004106 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004107 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004108 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004109 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004110 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004111 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004112 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004113 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004114 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004115 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004116 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004117 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004118 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004119 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004120 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004121 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004122 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004123 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004124 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004125 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004126 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004127 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004128 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004129 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004130 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004131 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004132 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004133 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004134 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004135 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004136 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004137 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004138 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004139 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004140 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004141 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004142 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004143 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00004144 case CXCursor_SEHLeaveStmt:
4145 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004146 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004147 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004148 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004149 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00004150 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004151 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00004152 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004153 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00004154 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004155 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00004156 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004157 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00004158 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004159 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004160 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004161 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004162 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004163 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004164 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004165 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004166 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004167 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004168 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004169 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004170 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004171 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004172 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004173 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004174 case CXCursor_PackedAttr:
4175 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00004176 case CXCursor_PureAttr:
4177 return cxstring::createRef("attribute(pure)");
4178 case CXCursor_ConstAttr:
4179 return cxstring::createRef("attribute(const)");
4180 case CXCursor_NoDuplicateAttr:
4181 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00004182 case CXCursor_CUDAConstantAttr:
4183 return cxstring::createRef("attribute(constant)");
4184 case CXCursor_CUDADeviceAttr:
4185 return cxstring::createRef("attribute(device)");
4186 case CXCursor_CUDAGlobalAttr:
4187 return cxstring::createRef("attribute(global)");
4188 case CXCursor_CUDAHostAttr:
4189 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00004190 case CXCursor_CUDASharedAttr:
4191 return cxstring::createRef("attribute(shared)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004192 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004193 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004194 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004195 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00004196 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004197 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004198 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004199 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004200 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004201 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00004202 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004203 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00004204 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004205 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004206 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004207 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004208 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004209 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004210 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004211 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004212 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004213 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004214 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004215 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004216 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004217 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004218 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004219 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004220 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004221 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004222 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004223 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004224 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004225 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004226 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004227 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004228 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004229 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004230 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004231 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004232 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004233 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004234 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004235 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004236 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004237 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004238 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004239 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004240 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004241 return cxstring::createRef("OMPParallelDirective");
4242 case CXCursor_OMPSimdDirective:
4243 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004244 case CXCursor_OMPForDirective:
4245 return cxstring::createRef("OMPForDirective");
Alexander Musmanf82886e2014-09-18 05:12:34 +00004246 case CXCursor_OMPForSimdDirective:
4247 return cxstring::createRef("OMPForSimdDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004248 case CXCursor_OMPSectionsDirective:
4249 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004250 case CXCursor_OMPSectionDirective:
4251 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004252 case CXCursor_OMPSingleDirective:
4253 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004254 case CXCursor_OMPMasterDirective:
4255 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004256 case CXCursor_OMPCriticalDirective:
4257 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004258 case CXCursor_OMPParallelForDirective:
4259 return cxstring::createRef("OMPParallelForDirective");
Alexander Musmane4e893b2014-09-23 09:33:00 +00004260 case CXCursor_OMPParallelForSimdDirective:
4261 return cxstring::createRef("OMPParallelForSimdDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004262 case CXCursor_OMPParallelSectionsDirective:
4263 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004264 case CXCursor_OMPTaskDirective:
4265 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004266 case CXCursor_OMPTaskyieldDirective:
4267 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004268 case CXCursor_OMPBarrierDirective:
4269 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004270 case CXCursor_OMPTaskwaitDirective:
4271 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00004272 case CXCursor_OMPTaskgroupDirective:
4273 return cxstring::createRef("OMPTaskgroupDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00004274 case CXCursor_OMPFlushDirective:
4275 return cxstring::createRef("OMPFlushDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004276 case CXCursor_OMPOrderedDirective:
4277 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00004278 case CXCursor_OMPAtomicDirective:
4279 return cxstring::createRef("OMPAtomicDirective");
Alexey Bataev0bd520b2014-09-19 08:19:49 +00004280 case CXCursor_OMPTargetDirective:
4281 return cxstring::createRef("OMPTargetDirective");
Alexey Bataev13314bf2014-10-09 04:18:56 +00004282 case CXCursor_OMPTeamsDirective:
4283 return cxstring::createRef("OMPTeamsDirective");
Francisco Lopes da Silva975a9f62015-01-21 16:24:11 +00004284 case CXCursor_OverloadCandidate:
4285 return cxstring::createRef("OverloadCandidate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004286 }
4287
4288 llvm_unreachable("Unhandled CXCursorKind");
4289}
4290
4291struct GetCursorData {
4292 SourceLocation TokenBeginLoc;
4293 bool PointsAtMacroArgExpansion;
4294 bool VisitedObjCPropertyImplDecl;
4295 SourceLocation VisitedDeclaratorDeclStartLoc;
4296 CXCursor &BestCursor;
4297
4298 GetCursorData(SourceManager &SM,
4299 SourceLocation tokenBegin, CXCursor &outputCursor)
4300 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4301 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4302 VisitedObjCPropertyImplDecl = false;
4303 }
4304};
4305
4306static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4307 CXCursor parent,
4308 CXClientData client_data) {
4309 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4310 CXCursor *BestCursor = &Data->BestCursor;
4311
4312 // If we point inside a macro argument we should provide info of what the
4313 // token is so use the actual cursor, don't replace it with a macro expansion
4314 // cursor.
4315 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4316 return CXChildVisit_Recurse;
4317
4318 if (clang_isDeclaration(cursor.kind)) {
4319 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004320 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004321 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4322 if (MD->isImplicit())
4323 return CXChildVisit_Break;
4324
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004325 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004326 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4327 // Check that when we have multiple @class references in the same line,
4328 // that later ones do not override the previous ones.
4329 // If we have:
4330 // @class Foo, Bar;
4331 // source ranges for both start at '@', so 'Bar' will end up overriding
4332 // 'Foo' even though the cursor location was at 'Foo'.
4333 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4334 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004335 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004336 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4337 if (PrevID != ID &&
4338 !PrevID->isThisDeclarationADefinition() &&
4339 !ID->isThisDeclarationADefinition())
4340 return CXChildVisit_Break;
4341 }
4342
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004343 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004344 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4345 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4346 // Check that when we have multiple declarators in the same line,
4347 // that later ones do not override the previous ones.
4348 // If we have:
4349 // int Foo, Bar;
4350 // source ranges for both start at 'int', so 'Bar' will end up overriding
4351 // 'Foo' even though the cursor location was at 'Foo'.
4352 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4353 return CXChildVisit_Break;
4354 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4355
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004356 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004357 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4358 (void)PropImp;
4359 // Check that when we have multiple @synthesize in the same line,
4360 // that later ones do not override the previous ones.
4361 // If we have:
4362 // @synthesize Foo, Bar;
4363 // source ranges for both start at '@', so 'Bar' will end up overriding
4364 // 'Foo' even though the cursor location was at 'Foo'.
4365 if (Data->VisitedObjCPropertyImplDecl)
4366 return CXChildVisit_Break;
4367 Data->VisitedObjCPropertyImplDecl = true;
4368 }
4369 }
4370
4371 if (clang_isExpression(cursor.kind) &&
4372 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004373 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004374 // Avoid having the cursor of an expression replace the declaration cursor
4375 // when the expression source range overlaps the declaration range.
4376 // This can happen for C++ constructor expressions whose range generally
4377 // include the variable declaration, e.g.:
4378 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4379 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4380 D->getLocation() == Data->TokenBeginLoc)
4381 return CXChildVisit_Break;
4382 }
4383 }
4384
4385 // If our current best cursor is the construction of a temporary object,
4386 // don't replace that cursor with a type reference, because we want
4387 // clang_getCursor() to point at the constructor.
4388 if (clang_isExpression(BestCursor->kind) &&
4389 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4390 cursor.kind == CXCursor_TypeRef) {
4391 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4392 // as having the actual point on the type reference.
4393 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4394 return CXChildVisit_Recurse;
4395 }
4396
4397 *BestCursor = cursor;
4398 return CXChildVisit_Recurse;
4399}
4400
4401CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004402 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004403 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004404 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004405 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004406
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004407 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004408 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4409
4410 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4411 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4412
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004413 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004414 CXFile SearchFile;
4415 unsigned SearchLine, SearchColumn;
4416 CXFile ResultFile;
4417 unsigned ResultLine, ResultColumn;
4418 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4419 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4420 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004421
4422 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4423 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004424 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004425 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004426 SearchFileName = clang_getFileName(SearchFile);
4427 ResultFileName = clang_getFileName(ResultFile);
4428 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4429 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004430 *Log << llvm::format("(%s:%d:%d) = %s",
4431 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4432 clang_getCString(KindSpelling))
4433 << llvm::format("(%s:%d:%d):%s%s",
4434 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4435 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004436 clang_disposeString(SearchFileName);
4437 clang_disposeString(ResultFileName);
4438 clang_disposeString(KindSpelling);
4439 clang_disposeString(USR);
4440
4441 CXCursor Definition = clang_getCursorDefinition(Result);
4442 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4443 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4444 CXString DefinitionKindSpelling
4445 = clang_getCursorKindSpelling(Definition.kind);
4446 CXFile DefinitionFile;
4447 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004448 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004449 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004450 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004451 *Log << llvm::format(" -> %s(%s:%d:%d)",
4452 clang_getCString(DefinitionKindSpelling),
4453 clang_getCString(DefinitionFileName),
4454 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004455 clang_disposeString(DefinitionFileName);
4456 clang_disposeString(DefinitionKindSpelling);
4457 }
4458 }
4459
4460 return Result;
4461}
4462
4463CXCursor clang_getNullCursor(void) {
4464 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4465}
4466
4467unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004468 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4469 // can't set consistently. For example, when visiting a DeclStmt we will set
4470 // it but we don't set it on the result of clang_getCursorDefinition for
4471 // a reference of the same declaration.
4472 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4473 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4474 // to provide that kind of info.
4475 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004476 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004477 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004478 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004479
Guy Benyei11169dd2012-12-18 14:30:41 +00004480 return X == Y;
4481}
4482
4483unsigned clang_hashCursor(CXCursor C) {
4484 unsigned Index = 0;
4485 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4486 Index = 1;
4487
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004488 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004489 std::make_pair(C.kind, C.data[Index]));
4490}
4491
4492unsigned clang_isInvalid(enum CXCursorKind K) {
4493 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4494}
4495
4496unsigned clang_isDeclaration(enum CXCursorKind K) {
4497 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4498 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4499}
4500
4501unsigned clang_isReference(enum CXCursorKind K) {
4502 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4503}
4504
4505unsigned clang_isExpression(enum CXCursorKind K) {
4506 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4507}
4508
4509unsigned clang_isStatement(enum CXCursorKind K) {
4510 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4511}
4512
4513unsigned clang_isAttribute(enum CXCursorKind K) {
4514 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4515}
4516
4517unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4518 return K == CXCursor_TranslationUnit;
4519}
4520
4521unsigned clang_isPreprocessing(enum CXCursorKind K) {
4522 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4523}
4524
4525unsigned clang_isUnexposed(enum CXCursorKind K) {
4526 switch (K) {
4527 case CXCursor_UnexposedDecl:
4528 case CXCursor_UnexposedExpr:
4529 case CXCursor_UnexposedStmt:
4530 case CXCursor_UnexposedAttr:
4531 return true;
4532 default:
4533 return false;
4534 }
4535}
4536
4537CXCursorKind clang_getCursorKind(CXCursor C) {
4538 return C.kind;
4539}
4540
4541CXSourceLocation clang_getCursorLocation(CXCursor C) {
4542 if (clang_isReference(C.kind)) {
4543 switch (C.kind) {
4544 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004545 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004546 = getCursorObjCSuperClassRef(C);
4547 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4548 }
4549
4550 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004551 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004552 = getCursorObjCProtocolRef(C);
4553 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4554 }
4555
4556 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004557 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004558 = getCursorObjCClassRef(C);
4559 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4560 }
4561
4562 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004563 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004564 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4565 }
4566
4567 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004568 std::pair<const TemplateDecl *, SourceLocation> P =
4569 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004570 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4571 }
4572
4573 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004574 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004575 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4576 }
4577
4578 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004579 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004580 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4581 }
4582
4583 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004584 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004585 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4586 }
4587
4588 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004589 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004590 if (!BaseSpec)
4591 return clang_getNullLocation();
4592
4593 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4594 return cxloc::translateSourceLocation(getCursorContext(C),
4595 TSInfo->getTypeLoc().getBeginLoc());
4596
4597 return cxloc::translateSourceLocation(getCursorContext(C),
4598 BaseSpec->getLocStart());
4599 }
4600
4601 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004602 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004603 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4604 }
4605
4606 case CXCursor_OverloadedDeclRef:
4607 return cxloc::translateSourceLocation(getCursorContext(C),
4608 getCursorOverloadedDeclRef(C).second);
4609
4610 default:
4611 // FIXME: Need a way to enumerate all non-reference cases.
4612 llvm_unreachable("Missed a reference kind");
4613 }
4614 }
4615
4616 if (clang_isExpression(C.kind))
4617 return cxloc::translateSourceLocation(getCursorContext(C),
4618 getLocationFromExpr(getCursorExpr(C)));
4619
4620 if (clang_isStatement(C.kind))
4621 return cxloc::translateSourceLocation(getCursorContext(C),
4622 getCursorStmt(C)->getLocStart());
4623
4624 if (C.kind == CXCursor_PreprocessingDirective) {
4625 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4626 return cxloc::translateSourceLocation(getCursorContext(C), L);
4627 }
4628
4629 if (C.kind == CXCursor_MacroExpansion) {
4630 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004631 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004632 return cxloc::translateSourceLocation(getCursorContext(C), L);
4633 }
4634
4635 if (C.kind == CXCursor_MacroDefinition) {
4636 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4637 return cxloc::translateSourceLocation(getCursorContext(C), L);
4638 }
4639
4640 if (C.kind == CXCursor_InclusionDirective) {
4641 SourceLocation L
4642 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4643 return cxloc::translateSourceLocation(getCursorContext(C), L);
4644 }
4645
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004646 if (clang_isAttribute(C.kind)) {
4647 SourceLocation L
4648 = cxcursor::getCursorAttr(C)->getLocation();
4649 return cxloc::translateSourceLocation(getCursorContext(C), L);
4650 }
4651
Guy Benyei11169dd2012-12-18 14:30:41 +00004652 if (!clang_isDeclaration(C.kind))
4653 return clang_getNullLocation();
4654
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004655 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004656 if (!D)
4657 return clang_getNullLocation();
4658
4659 SourceLocation Loc = D->getLocation();
4660 // FIXME: Multiple variables declared in a single declaration
4661 // currently lack the information needed to correctly determine their
4662 // ranges when accounting for the type-specifier. We use context
4663 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4664 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004665 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004666 if (!cxcursor::isFirstInDeclGroup(C))
4667 Loc = VD->getLocation();
4668 }
4669
4670 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004671 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004672 Loc = MD->getSelectorStartLoc();
4673
4674 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4675}
4676
4677} // end extern "C"
4678
4679CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4680 assert(TU);
4681
4682 // Guard against an invalid SourceLocation, or we may assert in one
4683 // of the following calls.
4684 if (SLoc.isInvalid())
4685 return clang_getNullCursor();
4686
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004687 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004688
4689 // Translate the given source location to make it point at the beginning of
4690 // the token under the cursor.
4691 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4692 CXXUnit->getASTContext().getLangOpts());
4693
4694 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4695 if (SLoc.isValid()) {
4696 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4697 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4698 /*VisitPreprocessorLast=*/true,
4699 /*VisitIncludedEntities=*/false,
4700 SourceLocation(SLoc));
4701 CursorVis.visitFileRegion();
4702 }
4703
4704 return Result;
4705}
4706
4707static SourceRange getRawCursorExtent(CXCursor C) {
4708 if (clang_isReference(C.kind)) {
4709 switch (C.kind) {
4710 case CXCursor_ObjCSuperClassRef:
4711 return getCursorObjCSuperClassRef(C).second;
4712
4713 case CXCursor_ObjCProtocolRef:
4714 return getCursorObjCProtocolRef(C).second;
4715
4716 case CXCursor_ObjCClassRef:
4717 return getCursorObjCClassRef(C).second;
4718
4719 case CXCursor_TypeRef:
4720 return getCursorTypeRef(C).second;
4721
4722 case CXCursor_TemplateRef:
4723 return getCursorTemplateRef(C).second;
4724
4725 case CXCursor_NamespaceRef:
4726 return getCursorNamespaceRef(C).second;
4727
4728 case CXCursor_MemberRef:
4729 return getCursorMemberRef(C).second;
4730
4731 case CXCursor_CXXBaseSpecifier:
4732 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4733
4734 case CXCursor_LabelRef:
4735 return getCursorLabelRef(C).second;
4736
4737 case CXCursor_OverloadedDeclRef:
4738 return getCursorOverloadedDeclRef(C).second;
4739
4740 case CXCursor_VariableRef:
4741 return getCursorVariableRef(C).second;
4742
4743 default:
4744 // FIXME: Need a way to enumerate all non-reference cases.
4745 llvm_unreachable("Missed a reference kind");
4746 }
4747 }
4748
4749 if (clang_isExpression(C.kind))
4750 return getCursorExpr(C)->getSourceRange();
4751
4752 if (clang_isStatement(C.kind))
4753 return getCursorStmt(C)->getSourceRange();
4754
4755 if (clang_isAttribute(C.kind))
4756 return getCursorAttr(C)->getRange();
4757
4758 if (C.kind == CXCursor_PreprocessingDirective)
4759 return cxcursor::getCursorPreprocessingDirective(C);
4760
4761 if (C.kind == CXCursor_MacroExpansion) {
4762 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004763 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004764 return TU->mapRangeFromPreamble(Range);
4765 }
4766
4767 if (C.kind == CXCursor_MacroDefinition) {
4768 ASTUnit *TU = getCursorASTUnit(C);
4769 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4770 return TU->mapRangeFromPreamble(Range);
4771 }
4772
4773 if (C.kind == CXCursor_InclusionDirective) {
4774 ASTUnit *TU = getCursorASTUnit(C);
4775 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4776 return TU->mapRangeFromPreamble(Range);
4777 }
4778
4779 if (C.kind == CXCursor_TranslationUnit) {
4780 ASTUnit *TU = getCursorASTUnit(C);
4781 FileID MainID = TU->getSourceManager().getMainFileID();
4782 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4783 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4784 return SourceRange(Start, End);
4785 }
4786
4787 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004788 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004789 if (!D)
4790 return SourceRange();
4791
4792 SourceRange R = D->getSourceRange();
4793 // FIXME: Multiple variables declared in a single declaration
4794 // currently lack the information needed to correctly determine their
4795 // ranges when accounting for the type-specifier. We use context
4796 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4797 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004798 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004799 if (!cxcursor::isFirstInDeclGroup(C))
4800 R.setBegin(VD->getLocation());
4801 }
4802 return R;
4803 }
4804 return SourceRange();
4805}
4806
4807/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4808/// the decl-specifier-seq for declarations.
4809static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4810 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004811 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004812 if (!D)
4813 return SourceRange();
4814
4815 SourceRange R = D->getSourceRange();
4816
4817 // Adjust the start of the location for declarations preceded by
4818 // declaration specifiers.
4819 SourceLocation StartLoc;
4820 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4821 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4822 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004823 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004824 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4825 StartLoc = TI->getTypeLoc().getLocStart();
4826 }
4827
4828 if (StartLoc.isValid() && R.getBegin().isValid() &&
4829 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4830 R.setBegin(StartLoc);
4831
4832 // FIXME: Multiple variables declared in a single declaration
4833 // currently lack the information needed to correctly determine their
4834 // ranges when accounting for the type-specifier. We use context
4835 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4836 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004837 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004838 if (!cxcursor::isFirstInDeclGroup(C))
4839 R.setBegin(VD->getLocation());
4840 }
4841
4842 return R;
4843 }
4844
4845 return getRawCursorExtent(C);
4846}
4847
4848extern "C" {
4849
4850CXSourceRange clang_getCursorExtent(CXCursor C) {
4851 SourceRange R = getRawCursorExtent(C);
4852 if (R.isInvalid())
4853 return clang_getNullRange();
4854
4855 return cxloc::translateSourceRange(getCursorContext(C), R);
4856}
4857
4858CXCursor clang_getCursorReferenced(CXCursor C) {
4859 if (clang_isInvalid(C.kind))
4860 return clang_getNullCursor();
4861
4862 CXTranslationUnit tu = getCursorTU(C);
4863 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004864 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004865 if (!D)
4866 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004867 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004868 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004869 if (const ObjCPropertyImplDecl *PropImpl =
4870 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004871 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4872 return MakeCXCursor(Property, tu);
4873
4874 return C;
4875 }
4876
4877 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004878 const Expr *E = getCursorExpr(C);
4879 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004880 if (D) {
4881 CXCursor declCursor = MakeCXCursor(D, tu);
4882 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4883 declCursor);
4884 return declCursor;
4885 }
4886
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004887 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004888 return MakeCursorOverloadedDeclRef(Ovl, tu);
4889
4890 return clang_getNullCursor();
4891 }
4892
4893 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004894 const Stmt *S = getCursorStmt(C);
4895 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004896 if (LabelDecl *label = Goto->getLabel())
4897 if (LabelStmt *labelS = label->getStmt())
4898 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4899
4900 return clang_getNullCursor();
4901 }
Richard Smith66a81862015-05-04 02:25:31 +00004902
Guy Benyei11169dd2012-12-18 14:30:41 +00004903 if (C.kind == CXCursor_MacroExpansion) {
Richard Smith66a81862015-05-04 02:25:31 +00004904 if (const MacroDefinitionRecord *Def =
4905 getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004906 return MakeMacroDefinitionCursor(Def, tu);
4907 }
4908
4909 if (!clang_isReference(C.kind))
4910 return clang_getNullCursor();
4911
4912 switch (C.kind) {
4913 case CXCursor_ObjCSuperClassRef:
4914 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4915
4916 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004917 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4918 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004919 return MakeCXCursor(Def, tu);
4920
4921 return MakeCXCursor(Prot, tu);
4922 }
4923
4924 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004925 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4926 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004927 return MakeCXCursor(Def, tu);
4928
4929 return MakeCXCursor(Class, tu);
4930 }
4931
4932 case CXCursor_TypeRef:
4933 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4934
4935 case CXCursor_TemplateRef:
4936 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4937
4938 case CXCursor_NamespaceRef:
4939 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4940
4941 case CXCursor_MemberRef:
4942 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4943
4944 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004945 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004946 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4947 tu ));
4948 }
4949
4950 case CXCursor_LabelRef:
4951 // FIXME: We end up faking the "parent" declaration here because we
4952 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004953 return MakeCXCursor(getCursorLabelRef(C).first,
4954 cxtu::getASTUnit(tu)->getASTContext()
4955 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004956 tu);
4957
4958 case CXCursor_OverloadedDeclRef:
4959 return C;
4960
4961 case CXCursor_VariableRef:
4962 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4963
4964 default:
4965 // We would prefer to enumerate all non-reference cursor kinds here.
4966 llvm_unreachable("Unhandled reference cursor kind");
4967 }
4968}
4969
4970CXCursor clang_getCursorDefinition(CXCursor C) {
4971 if (clang_isInvalid(C.kind))
4972 return clang_getNullCursor();
4973
4974 CXTranslationUnit TU = getCursorTU(C);
4975
4976 bool WasReference = false;
4977 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4978 C = clang_getCursorReferenced(C);
4979 WasReference = true;
4980 }
4981
4982 if (C.kind == CXCursor_MacroExpansion)
4983 return clang_getCursorReferenced(C);
4984
4985 if (!clang_isDeclaration(C.kind))
4986 return clang_getNullCursor();
4987
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004988 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004989 if (!D)
4990 return clang_getNullCursor();
4991
4992 switch (D->getKind()) {
4993 // Declaration kinds that don't really separate the notions of
4994 // declaration and definition.
4995 case Decl::Namespace:
4996 case Decl::Typedef:
4997 case Decl::TypeAlias:
4998 case Decl::TypeAliasTemplate:
4999 case Decl::TemplateTypeParm:
5000 case Decl::EnumConstant:
5001 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00005002 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005003 case Decl::IndirectField:
5004 case Decl::ObjCIvar:
5005 case Decl::ObjCAtDefsField:
5006 case Decl::ImplicitParam:
5007 case Decl::ParmVar:
5008 case Decl::NonTypeTemplateParm:
5009 case Decl::TemplateTemplateParm:
5010 case Decl::ObjCCategoryImpl:
5011 case Decl::ObjCImplementation:
5012 case Decl::AccessSpec:
5013 case Decl::LinkageSpec:
5014 case Decl::ObjCPropertyImpl:
5015 case Decl::FileScopeAsm:
5016 case Decl::StaticAssert:
5017 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00005018 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00005019 case Decl::Label: // FIXME: Is this right??
5020 case Decl::ClassScopeFunctionSpecialization:
5021 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00005022 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00005023 return C;
5024
5025 // Declaration kinds that don't make any sense here, but are
5026 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00005027 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005028 case Decl::TranslationUnit:
Richard Smithf19e1272015-03-07 00:04:49 +00005029 case Decl::ExternCContext:
Guy Benyei11169dd2012-12-18 14:30:41 +00005030 break;
5031
5032 // Declaration kinds for which the definition is not resolvable.
5033 case Decl::UnresolvedUsingTypename:
5034 case Decl::UnresolvedUsingValue:
5035 break;
5036
5037 case Decl::UsingDirective:
5038 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
5039 TU);
5040
5041 case Decl::NamespaceAlias:
5042 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
5043
5044 case Decl::Enum:
5045 case Decl::Record:
5046 case Decl::CXXRecord:
5047 case Decl::ClassTemplateSpecialization:
5048 case Decl::ClassTemplatePartialSpecialization:
5049 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
5050 return MakeCXCursor(Def, TU);
5051 return clang_getNullCursor();
5052
5053 case Decl::Function:
5054 case Decl::CXXMethod:
5055 case Decl::CXXConstructor:
5056 case Decl::CXXDestructor:
5057 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00005058 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005059 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00005060 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005061 return clang_getNullCursor();
5062 }
5063
Larisse Voufo39a1e502013-08-06 01:03:05 +00005064 case Decl::Var:
5065 case Decl::VarTemplateSpecialization:
5066 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00005067 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005068 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005069 return MakeCXCursor(Def, TU);
5070 return clang_getNullCursor();
5071 }
5072
5073 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00005074 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005075 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
5076 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
5077 return clang_getNullCursor();
5078 }
5079
5080 case Decl::ClassTemplate: {
5081 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
5082 ->getDefinition())
5083 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
5084 TU);
5085 return clang_getNullCursor();
5086 }
5087
Larisse Voufo39a1e502013-08-06 01:03:05 +00005088 case Decl::VarTemplate: {
5089 if (VarDecl *Def =
5090 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
5091 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
5092 return clang_getNullCursor();
5093 }
5094
Guy Benyei11169dd2012-12-18 14:30:41 +00005095 case Decl::Using:
5096 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
5097 D->getLocation(), TU);
5098
5099 case Decl::UsingShadow:
5100 return clang_getCursorDefinition(
5101 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
5102 TU));
5103
5104 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005105 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005106 if (Method->isThisDeclarationADefinition())
5107 return C;
5108
5109 // Dig out the method definition in the associated
5110 // @implementation, if we have it.
5111 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005112 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005113 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
5114 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
5115 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
5116 Method->isInstanceMethod()))
5117 if (Def->isThisDeclarationADefinition())
5118 return MakeCXCursor(Def, TU);
5119
5120 return clang_getNullCursor();
5121 }
5122
5123 case Decl::ObjCCategory:
5124 if (ObjCCategoryImplDecl *Impl
5125 = cast<ObjCCategoryDecl>(D)->getImplementation())
5126 return MakeCXCursor(Impl, TU);
5127 return clang_getNullCursor();
5128
5129 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005130 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005131 return MakeCXCursor(Def, TU);
5132 return clang_getNullCursor();
5133
5134 case Decl::ObjCInterface: {
5135 // There are two notions of a "definition" for an Objective-C
5136 // class: the interface and its implementation. When we resolved a
5137 // reference to an Objective-C class, produce the @interface as
5138 // the definition; when we were provided with the interface,
5139 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005140 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005141 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005142 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005143 return MakeCXCursor(Def, TU);
5144 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
5145 return MakeCXCursor(Impl, TU);
5146 return clang_getNullCursor();
5147 }
5148
5149 case Decl::ObjCProperty:
5150 // FIXME: We don't really know where to find the
5151 // ObjCPropertyImplDecls that implement this property.
5152 return clang_getNullCursor();
5153
5154 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005155 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005156 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005157 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005158 return MakeCXCursor(Def, TU);
5159
5160 return clang_getNullCursor();
5161
5162 case Decl::Friend:
5163 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
5164 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5165 return clang_getNullCursor();
5166
5167 case Decl::FriendTemplate:
5168 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
5169 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5170 return clang_getNullCursor();
5171 }
5172
5173 return clang_getNullCursor();
5174}
5175
5176unsigned clang_isCursorDefinition(CXCursor C) {
5177 if (!clang_isDeclaration(C.kind))
5178 return 0;
5179
5180 return clang_getCursorDefinition(C) == C;
5181}
5182
5183CXCursor clang_getCanonicalCursor(CXCursor C) {
5184 if (!clang_isDeclaration(C.kind))
5185 return C;
5186
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005187 if (const Decl *D = getCursorDecl(C)) {
5188 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005189 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5190 return MakeCXCursor(CatD, getCursorTU(C));
5191
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005192 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5193 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00005194 return MakeCXCursor(IFD, getCursorTU(C));
5195
5196 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5197 }
5198
5199 return C;
5200}
5201
5202int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5203 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5204}
5205
5206unsigned clang_getNumOverloadedDecls(CXCursor C) {
5207 if (C.kind != CXCursor_OverloadedDeclRef)
5208 return 0;
5209
5210 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005211 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005212 return E->getNumDecls();
5213
5214 if (OverloadedTemplateStorage *S
5215 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5216 return S->size();
5217
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005218 const Decl *D = Storage.get<const Decl *>();
5219 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005220 return Using->shadow_size();
5221
5222 return 0;
5223}
5224
5225CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5226 if (cursor.kind != CXCursor_OverloadedDeclRef)
5227 return clang_getNullCursor();
5228
5229 if (index >= clang_getNumOverloadedDecls(cursor))
5230 return clang_getNullCursor();
5231
5232 CXTranslationUnit TU = getCursorTU(cursor);
5233 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005234 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005235 return MakeCXCursor(E->decls_begin()[index], TU);
5236
5237 if (OverloadedTemplateStorage *S
5238 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5239 return MakeCXCursor(S->begin()[index], TU);
5240
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005241 const Decl *D = Storage.get<const Decl *>();
5242 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005243 // FIXME: This is, unfortunately, linear time.
5244 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5245 std::advance(Pos, index);
5246 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5247 }
5248
5249 return clang_getNullCursor();
5250}
5251
5252void clang_getDefinitionSpellingAndExtent(CXCursor C,
5253 const char **startBuf,
5254 const char **endBuf,
5255 unsigned *startLine,
5256 unsigned *startColumn,
5257 unsigned *endLine,
5258 unsigned *endColumn) {
5259 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005260 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005261 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5262
5263 SourceManager &SM = FD->getASTContext().getSourceManager();
5264 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5265 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5266 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5267 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5268 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5269 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5270}
5271
5272
5273CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5274 unsigned PieceIndex) {
5275 RefNamePieces Pieces;
5276
5277 switch (C.kind) {
5278 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005279 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005280 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5281 E->getQualifierLoc().getSourceRange());
5282 break;
5283
5284 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005285 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005286 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
5287 E->getQualifierLoc().getSourceRange(),
5288 E->getOptionalExplicitTemplateArgs());
5289 break;
5290
5291 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005292 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005293 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005294 const Expr *Callee = OCE->getCallee();
5295 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005296 Callee = ICE->getSubExpr();
5297
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005298 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005299 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5300 DRE->getQualifierLoc().getSourceRange());
5301 }
5302 break;
5303
5304 default:
5305 break;
5306 }
5307
5308 if (Pieces.empty()) {
5309 if (PieceIndex == 0)
5310 return clang_getCursorExtent(C);
5311 } else if (PieceIndex < Pieces.size()) {
5312 SourceRange R = Pieces[PieceIndex];
5313 if (R.isValid())
5314 return cxloc::translateSourceRange(getCursorContext(C), R);
5315 }
5316
5317 return clang_getNullRange();
5318}
5319
5320void clang_enableStackTraces(void) {
5321 llvm::sys::PrintStackTraceOnErrorSignal();
5322}
5323
5324void clang_executeOnThread(void (*fn)(void*), void *user_data,
5325 unsigned stack_size) {
5326 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5327}
5328
5329} // end: extern "C"
5330
5331//===----------------------------------------------------------------------===//
5332// Token-based Operations.
5333//===----------------------------------------------------------------------===//
5334
5335/* CXToken layout:
5336 * int_data[0]: a CXTokenKind
5337 * int_data[1]: starting token location
5338 * int_data[2]: token length
5339 * int_data[3]: reserved
5340 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5341 * otherwise unused.
5342 */
5343extern "C" {
5344
5345CXTokenKind clang_getTokenKind(CXToken CXTok) {
5346 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5347}
5348
5349CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5350 switch (clang_getTokenKind(CXTok)) {
5351 case CXToken_Identifier:
5352 case CXToken_Keyword:
5353 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005354 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005355 ->getNameStart());
5356
5357 case CXToken_Literal: {
5358 // We have stashed the starting pointer in the ptr_data field. Use it.
5359 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005360 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005361 }
5362
5363 case CXToken_Punctuation:
5364 case CXToken_Comment:
5365 break;
5366 }
5367
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005368 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005369 LOG_BAD_TU(TU);
5370 return cxstring::createEmpty();
5371 }
5372
Guy Benyei11169dd2012-12-18 14:30:41 +00005373 // We have to find the starting buffer pointer the hard way, by
5374 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005375 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005376 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005377 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005378
5379 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5380 std::pair<FileID, unsigned> LocInfo
5381 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5382 bool Invalid = false;
5383 StringRef Buffer
5384 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5385 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005386 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005387
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005388 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005389}
5390
5391CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005392 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005393 LOG_BAD_TU(TU);
5394 return clang_getNullLocation();
5395 }
5396
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005397 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005398 if (!CXXUnit)
5399 return clang_getNullLocation();
5400
5401 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5402 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5403}
5404
5405CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005406 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005407 LOG_BAD_TU(TU);
5408 return clang_getNullRange();
5409 }
5410
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005411 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005412 if (!CXXUnit)
5413 return clang_getNullRange();
5414
5415 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5416 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5417}
5418
5419static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5420 SmallVectorImpl<CXToken> &CXTokens) {
5421 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5422 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005423 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005424 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005425 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005426
5427 // Cannot tokenize across files.
5428 if (BeginLocInfo.first != EndLocInfo.first)
5429 return;
5430
5431 // Create a lexer
5432 bool Invalid = false;
5433 StringRef Buffer
5434 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5435 if (Invalid)
5436 return;
5437
5438 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5439 CXXUnit->getASTContext().getLangOpts(),
5440 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5441 Lex.SetCommentRetentionState(true);
5442
5443 // Lex tokens until we hit the end of the range.
5444 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5445 Token Tok;
5446 bool previousWasAt = false;
5447 do {
5448 // Lex the next token
5449 Lex.LexFromRawLexer(Tok);
5450 if (Tok.is(tok::eof))
5451 break;
5452
5453 // Initialize the CXToken.
5454 CXToken CXTok;
5455
5456 // - Common fields
5457 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5458 CXTok.int_data[2] = Tok.getLength();
5459 CXTok.int_data[3] = 0;
5460
5461 // - Kind-specific fields
5462 if (Tok.isLiteral()) {
5463 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005464 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005465 } else if (Tok.is(tok::raw_identifier)) {
5466 // Lookup the identifier to determine whether we have a keyword.
5467 IdentifierInfo *II
5468 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5469
5470 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5471 CXTok.int_data[0] = CXToken_Keyword;
5472 }
5473 else {
5474 CXTok.int_data[0] = Tok.is(tok::identifier)
5475 ? CXToken_Identifier
5476 : CXToken_Keyword;
5477 }
5478 CXTok.ptr_data = II;
5479 } else if (Tok.is(tok::comment)) {
5480 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005481 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005482 } else {
5483 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005484 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005485 }
5486 CXTokens.push_back(CXTok);
5487 previousWasAt = Tok.is(tok::at);
5488 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5489}
5490
5491void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5492 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005493 LOG_FUNC_SECTION {
5494 *Log << TU << ' ' << Range;
5495 }
5496
Guy Benyei11169dd2012-12-18 14:30:41 +00005497 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005498 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005499 if (NumTokens)
5500 *NumTokens = 0;
5501
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005502 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005503 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005504 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005505 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005506
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005507 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005508 if (!CXXUnit || !Tokens || !NumTokens)
5509 return;
5510
5511 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5512
5513 SourceRange R = cxloc::translateCXSourceRange(Range);
5514 if (R.isInvalid())
5515 return;
5516
5517 SmallVector<CXToken, 32> CXTokens;
5518 getTokens(CXXUnit, R, CXTokens);
5519
5520 if (CXTokens.empty())
5521 return;
5522
5523 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5524 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5525 *NumTokens = CXTokens.size();
5526}
5527
5528void clang_disposeTokens(CXTranslationUnit TU,
5529 CXToken *Tokens, unsigned NumTokens) {
5530 free(Tokens);
5531}
5532
5533} // end: extern "C"
5534
5535//===----------------------------------------------------------------------===//
5536// Token annotation APIs.
5537//===----------------------------------------------------------------------===//
5538
Guy Benyei11169dd2012-12-18 14:30:41 +00005539static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5540 CXCursor parent,
5541 CXClientData client_data);
5542static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5543 CXClientData client_data);
5544
5545namespace {
5546class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005547 CXToken *Tokens;
5548 CXCursor *Cursors;
5549 unsigned NumTokens;
5550 unsigned TokIdx;
5551 unsigned PreprocessingTokIdx;
5552 CursorVisitor AnnotateVis;
5553 SourceManager &SrcMgr;
5554 bool HasContextSensitiveKeywords;
5555
5556 struct PostChildrenInfo {
5557 CXCursor Cursor;
5558 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005559 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005560 unsigned BeforeChildrenTokenIdx;
5561 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005562 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005563
5564 CXToken &getTok(unsigned Idx) {
5565 assert(Idx < NumTokens);
5566 return Tokens[Idx];
5567 }
5568 const CXToken &getTok(unsigned Idx) const {
5569 assert(Idx < NumTokens);
5570 return Tokens[Idx];
5571 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005572 bool MoreTokens() const { return TokIdx < NumTokens; }
5573 unsigned NextToken() const { return TokIdx; }
5574 void AdvanceToken() { ++TokIdx; }
5575 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005576 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005577 }
5578 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005579 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005580 }
5581 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005582 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005583 }
5584
5585 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005586 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005587 SourceRange);
5588
5589public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005590 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005591 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005592 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005593 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005594 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005595 AnnotateTokensVisitor, this,
5596 /*VisitPreprocessorLast=*/true,
5597 /*VisitIncludedEntities=*/false,
5598 RegionOfInterest,
5599 /*VisitDeclsOnly=*/false,
5600 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005601 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005602 HasContextSensitiveKeywords(false) { }
5603
5604 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5605 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5606 bool postVisitChildren(CXCursor cursor);
5607 void AnnotateTokens();
5608
5609 /// \brief Determine whether the annotator saw any cursors that have
5610 /// context-sensitive keywords.
5611 bool hasContextSensitiveKeywords() const {
5612 return HasContextSensitiveKeywords;
5613 }
5614
5615 ~AnnotateTokensWorker() {
5616 assert(PostChildrenInfos.empty());
5617 }
5618};
5619}
5620
5621void AnnotateTokensWorker::AnnotateTokens() {
5622 // Walk the AST within the region of interest, annotating tokens
5623 // along the way.
5624 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005625}
Guy Benyei11169dd2012-12-18 14:30:41 +00005626
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005627static inline void updateCursorAnnotation(CXCursor &Cursor,
5628 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005629 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005630 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005631 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005632}
5633
5634/// \brief It annotates and advances tokens with a cursor until the comparison
5635//// between the cursor location and the source range is the same as
5636/// \arg compResult.
5637///
5638/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5639/// Pass RangeOverlap to annotate tokens inside a range.
5640void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5641 RangeComparisonResult compResult,
5642 SourceRange range) {
5643 while (MoreTokens()) {
5644 const unsigned I = NextToken();
5645 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005646 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5647 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005648
5649 SourceLocation TokLoc = GetTokenLoc(I);
5650 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005651 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005652 AdvanceToken();
5653 continue;
5654 }
5655 break;
5656 }
5657}
5658
5659/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005660/// \returns true if it advanced beyond all macro tokens, false otherwise.
5661bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005662 CXCursor updateC,
5663 RangeComparisonResult compResult,
5664 SourceRange range) {
5665 assert(MoreTokens());
5666 assert(isFunctionMacroToken(NextToken()) &&
5667 "Should be called only for macro arg tokens");
5668
5669 // This works differently than annotateAndAdvanceTokens; because expanded
5670 // macro arguments can have arbitrary translation-unit source order, we do not
5671 // advance the token index one by one until a token fails the range test.
5672 // We only advance once past all of the macro arg tokens if all of them
5673 // pass the range test. If one of them fails we keep the token index pointing
5674 // at the start of the macro arg tokens so that the failing token will be
5675 // annotated by a subsequent annotation try.
5676
5677 bool atLeastOneCompFail = false;
5678
5679 unsigned I = NextToken();
5680 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5681 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5682 if (TokLoc.isFileID())
5683 continue; // not macro arg token, it's parens or comma.
5684 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5685 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5686 Cursors[I] = updateC;
5687 } else
5688 atLeastOneCompFail = true;
5689 }
5690
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005691 if (atLeastOneCompFail)
5692 return false;
5693
5694 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5695 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005696}
5697
5698enum CXChildVisitResult
5699AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005700 SourceRange cursorRange = getRawCursorExtent(cursor);
5701 if (cursorRange.isInvalid())
5702 return CXChildVisit_Recurse;
5703
5704 if (!HasContextSensitiveKeywords) {
5705 // Objective-C properties can have context-sensitive keywords.
5706 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005707 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005708 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5709 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5710 }
5711 // Objective-C methods can have context-sensitive keywords.
5712 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5713 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005714 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005715 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5716 if (Method->getObjCDeclQualifier())
5717 HasContextSensitiveKeywords = true;
5718 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005719 for (const auto *P : Method->params()) {
5720 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005721 HasContextSensitiveKeywords = true;
5722 break;
5723 }
5724 }
5725 }
5726 }
5727 }
5728 // C++ methods can have context-sensitive keywords.
5729 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005730 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005731 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5732 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5733 HasContextSensitiveKeywords = true;
5734 }
5735 }
5736 // C++ classes can have context-sensitive keywords.
5737 else if (cursor.kind == CXCursor_StructDecl ||
5738 cursor.kind == CXCursor_ClassDecl ||
5739 cursor.kind == CXCursor_ClassTemplate ||
5740 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005741 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005742 if (D->hasAttr<FinalAttr>())
5743 HasContextSensitiveKeywords = true;
5744 }
5745 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005746
5747 // Don't override a property annotation with its getter/setter method.
5748 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5749 parent.kind == CXCursor_ObjCPropertyDecl)
5750 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005751
5752 if (clang_isPreprocessing(cursor.kind)) {
5753 // Items in the preprocessing record are kept separate from items in
5754 // declarations, so we keep a separate token index.
5755 unsigned SavedTokIdx = TokIdx;
5756 TokIdx = PreprocessingTokIdx;
5757
5758 // Skip tokens up until we catch up to the beginning of the preprocessing
5759 // entry.
5760 while (MoreTokens()) {
5761 const unsigned I = NextToken();
5762 SourceLocation TokLoc = GetTokenLoc(I);
5763 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5764 case RangeBefore:
5765 AdvanceToken();
5766 continue;
5767 case RangeAfter:
5768 case RangeOverlap:
5769 break;
5770 }
5771 break;
5772 }
5773
5774 // Look at all of the tokens within this range.
5775 while (MoreTokens()) {
5776 const unsigned I = NextToken();
5777 SourceLocation TokLoc = GetTokenLoc(I);
5778 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5779 case RangeBefore:
5780 llvm_unreachable("Infeasible");
5781 case RangeAfter:
5782 break;
5783 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005784 // For macro expansions, just note where the beginning of the macro
5785 // expansion occurs.
5786 if (cursor.kind == CXCursor_MacroExpansion) {
5787 if (TokLoc == cursorRange.getBegin())
5788 Cursors[I] = cursor;
5789 AdvanceToken();
5790 break;
5791 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005792 // We may have already annotated macro names inside macro definitions.
5793 if (Cursors[I].kind != CXCursor_MacroExpansion)
5794 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005795 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005796 continue;
5797 }
5798 break;
5799 }
5800
5801 // Save the preprocessing token index; restore the non-preprocessing
5802 // token index.
5803 PreprocessingTokIdx = TokIdx;
5804 TokIdx = SavedTokIdx;
5805 return CXChildVisit_Recurse;
5806 }
5807
5808 if (cursorRange.isInvalid())
5809 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005810
5811 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005812 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005813 const enum CXCursorKind K = clang_getCursorKind(parent);
5814 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005815 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5816 // Attributes are annotated out-of-order, skip tokens until we reach it.
5817 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005818 ? clang_getNullCursor() : parent;
5819
5820 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5821
5822 // Avoid having the cursor of an expression "overwrite" the annotation of the
5823 // variable declaration that it belongs to.
5824 // This can happen for C++ constructor expressions whose range generally
5825 // include the variable declaration, e.g.:
5826 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005827 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005828 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005829 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005830 const unsigned I = NextToken();
5831 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5832 E->getLocStart() == D->getLocation() &&
5833 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005834 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005835 AdvanceToken();
5836 }
5837 }
5838 }
5839
5840 // Before recursing into the children keep some state that we are going
5841 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5842 // extra work after the child nodes are visited.
5843 // Note that we don't call VisitChildren here to avoid traversing statements
5844 // code-recursively which can blow the stack.
5845
5846 PostChildrenInfo Info;
5847 Info.Cursor = cursor;
5848 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005849 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005850 Info.BeforeChildrenTokenIdx = NextToken();
5851 PostChildrenInfos.push_back(Info);
5852
5853 return CXChildVisit_Recurse;
5854}
5855
5856bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5857 if (PostChildrenInfos.empty())
5858 return false;
5859 const PostChildrenInfo &Info = PostChildrenInfos.back();
5860 if (!clang_equalCursors(Info.Cursor, cursor))
5861 return false;
5862
5863 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5864 const unsigned AfterChildren = NextToken();
5865 SourceRange cursorRange = Info.CursorRange;
5866
5867 // Scan the tokens that are at the end of the cursor, but are not captured
5868 // but the child cursors.
5869 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5870
5871 // Scan the tokens that are at the beginning of the cursor, but are not
5872 // capture by the child cursors.
5873 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5874 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5875 break;
5876
5877 Cursors[I] = cursor;
5878 }
5879
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005880 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5881 // encountered the attribute cursor.
5882 if (clang_isAttribute(cursor.kind))
5883 TokIdx = Info.BeforeReachingCursorIdx;
5884
Guy Benyei11169dd2012-12-18 14:30:41 +00005885 PostChildrenInfos.pop_back();
5886 return false;
5887}
5888
5889static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5890 CXCursor parent,
5891 CXClientData client_data) {
5892 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5893}
5894
5895static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5896 CXClientData client_data) {
5897 return static_cast<AnnotateTokensWorker*>(client_data)->
5898 postVisitChildren(cursor);
5899}
5900
5901namespace {
5902
5903/// \brief Uses the macro expansions in the preprocessing record to find
5904/// and mark tokens that are macro arguments. This info is used by the
5905/// AnnotateTokensWorker.
5906class MarkMacroArgTokensVisitor {
5907 SourceManager &SM;
5908 CXToken *Tokens;
5909 unsigned NumTokens;
5910 unsigned CurIdx;
5911
5912public:
5913 MarkMacroArgTokensVisitor(SourceManager &SM,
5914 CXToken *tokens, unsigned numTokens)
5915 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5916
5917 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5918 if (cursor.kind != CXCursor_MacroExpansion)
5919 return CXChildVisit_Continue;
5920
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005921 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005922 if (macroRange.getBegin() == macroRange.getEnd())
5923 return CXChildVisit_Continue; // it's not a function macro.
5924
5925 for (; CurIdx < NumTokens; ++CurIdx) {
5926 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5927 macroRange.getBegin()))
5928 break;
5929 }
5930
5931 if (CurIdx == NumTokens)
5932 return CXChildVisit_Break;
5933
5934 for (; CurIdx < NumTokens; ++CurIdx) {
5935 SourceLocation tokLoc = getTokenLoc(CurIdx);
5936 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5937 break;
5938
5939 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5940 }
5941
5942 if (CurIdx == NumTokens)
5943 return CXChildVisit_Break;
5944
5945 return CXChildVisit_Continue;
5946 }
5947
5948private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005949 CXToken &getTok(unsigned Idx) {
5950 assert(Idx < NumTokens);
5951 return Tokens[Idx];
5952 }
5953 const CXToken &getTok(unsigned Idx) const {
5954 assert(Idx < NumTokens);
5955 return Tokens[Idx];
5956 }
5957
Guy Benyei11169dd2012-12-18 14:30:41 +00005958 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005959 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005960 }
5961
5962 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5963 // The third field is reserved and currently not used. Use it here
5964 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005965 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005966 }
5967};
5968
5969} // end anonymous namespace
5970
5971static CXChildVisitResult
5972MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5973 CXClientData client_data) {
5974 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5975 parent);
5976}
5977
5978namespace {
5979 struct clang_annotateTokens_Data {
5980 CXTranslationUnit TU;
5981 ASTUnit *CXXUnit;
5982 CXToken *Tokens;
5983 unsigned NumTokens;
5984 CXCursor *Cursors;
5985 };
5986}
5987
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005988/// \brief Used by \c annotatePreprocessorTokens.
5989/// \returns true if lexing was finished, false otherwise.
5990static bool lexNext(Lexer &Lex, Token &Tok,
5991 unsigned &NextIdx, unsigned NumTokens) {
5992 if (NextIdx >= NumTokens)
5993 return true;
5994
5995 ++NextIdx;
5996 Lex.LexFromRawLexer(Tok);
5997 if (Tok.is(tok::eof))
5998 return true;
5999
6000 return false;
6001}
6002
Guy Benyei11169dd2012-12-18 14:30:41 +00006003static void annotatePreprocessorTokens(CXTranslationUnit TU,
6004 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006005 CXCursor *Cursors,
6006 CXToken *Tokens,
6007 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006008 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006009
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006010 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00006011 SourceManager &SourceMgr = CXXUnit->getSourceManager();
6012 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006013 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00006014 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006015 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00006016
6017 if (BeginLocInfo.first != EndLocInfo.first)
6018 return;
6019
6020 StringRef Buffer;
6021 bool Invalid = false;
6022 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
6023 if (Buffer.empty() || Invalid)
6024 return;
6025
6026 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
6027 CXXUnit->getASTContext().getLangOpts(),
6028 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
6029 Buffer.end());
6030 Lex.SetCommentRetentionState(true);
6031
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006032 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006033 // Lex tokens in raw mode until we hit the end of the range, to avoid
6034 // entering #includes or expanding macros.
6035 while (true) {
6036 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006037 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6038 break;
6039 unsigned TokIdx = NextIdx-1;
6040 assert(Tok.getLocation() ==
6041 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006042
6043 reprocess:
6044 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006045 // We have found a preprocessing directive. Annotate the tokens
6046 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00006047 //
6048 // FIXME: Some simple tests here could identify macro definitions and
6049 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006050
6051 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006052 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6053 break;
6054
Craig Topper69186e72014-06-08 08:38:04 +00006055 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00006056 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006057 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6058 break;
6059
6060 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00006061 IdentifierInfo &II =
6062 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006063 SourceLocation MappedTokLoc =
6064 CXXUnit->mapLocationToPreamble(Tok.getLocation());
6065 MI = getMacroInfo(II, MappedTokLoc, TU);
6066 }
6067 }
6068
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006069 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00006070 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006071 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
6072 finished = true;
6073 break;
6074 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006075 // If we are in a macro definition, check if the token was ever a
6076 // macro name and annotate it if that's the case.
6077 if (MI) {
6078 SourceLocation SaveLoc = Tok.getLocation();
6079 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
Richard Smith66a81862015-05-04 02:25:31 +00006080 MacroDefinitionRecord *MacroDef =
6081 checkForMacroInMacroDefinition(MI, Tok, TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006082 Tok.setLocation(SaveLoc);
6083 if (MacroDef)
Richard Smith66a81862015-05-04 02:25:31 +00006084 Cursors[NextIdx - 1] =
6085 MakeMacroExpansionCursor(MacroDef, Tok.getLocation(), TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006086 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006087 } while (!Tok.isAtStartOfLine());
6088
6089 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
6090 assert(TokIdx <= LastIdx);
6091 SourceLocation EndLoc =
6092 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
6093 CXCursor Cursor =
6094 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
6095
6096 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006097 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006098
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006099 if (finished)
6100 break;
6101 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00006102 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006103 }
6104}
6105
6106// This gets run a separate thread to avoid stack blowout.
6107static void clang_annotateTokensImpl(void *UserData) {
6108 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
6109 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
6110 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
6111 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
6112 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
6113
Dmitri Gribenko183436e2013-01-26 21:49:50 +00006114 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006115 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
6116 setThreadBackgroundPriority();
6117
6118 // Determine the region of interest, which contains all of the tokens.
6119 SourceRange RegionOfInterest;
6120 RegionOfInterest.setBegin(
6121 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
6122 RegionOfInterest.setEnd(
6123 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
6124 Tokens[NumTokens-1])));
6125
Guy Benyei11169dd2012-12-18 14:30:41 +00006126 // Relex the tokens within the source range to look for preprocessing
6127 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006128 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006129
6130 // If begin location points inside a macro argument, set it to the expansion
6131 // location so we can have the full context when annotating semantically.
6132 {
6133 SourceManager &SM = CXXUnit->getSourceManager();
6134 SourceLocation Loc =
6135 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
6136 if (Loc.isMacroID())
6137 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
6138 }
6139
Guy Benyei11169dd2012-12-18 14:30:41 +00006140 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
6141 // Search and mark tokens that are macro argument expansions.
6142 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
6143 Tokens, NumTokens);
6144 CursorVisitor MacroArgMarker(TU,
6145 MarkMacroArgTokensVisitorDelegate, &Visitor,
6146 /*VisitPreprocessorLast=*/true,
6147 /*VisitIncludedEntities=*/false,
6148 RegionOfInterest);
6149 MacroArgMarker.visitPreprocessedEntitiesInRegion();
6150 }
6151
6152 // Annotate all of the source locations in the region of interest that map to
6153 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006154 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00006155
6156 // FIXME: We use a ridiculous stack size here because the data-recursion
6157 // algorithm uses a large stack frame than the non-data recursive version,
6158 // and AnnotationTokensWorker currently transforms the data-recursion
6159 // algorithm back into a traditional recursion by explicitly calling
6160 // VisitChildren(). We will need to remove this explicit recursive call.
6161 W.AnnotateTokens();
6162
6163 // If we ran into any entities that involve context-sensitive keywords,
6164 // take another pass through the tokens to mark them as such.
6165 if (W.hasContextSensitiveKeywords()) {
6166 for (unsigned I = 0; I != NumTokens; ++I) {
6167 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
6168 continue;
6169
6170 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
6171 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006172 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006173 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
6174 if (Property->getPropertyAttributesAsWritten() != 0 &&
6175 llvm::StringSwitch<bool>(II->getName())
6176 .Case("readonly", true)
6177 .Case("assign", true)
6178 .Case("unsafe_unretained", true)
6179 .Case("readwrite", true)
6180 .Case("retain", true)
6181 .Case("copy", true)
6182 .Case("nonatomic", true)
6183 .Case("atomic", true)
6184 .Case("getter", true)
6185 .Case("setter", true)
6186 .Case("strong", true)
6187 .Case("weak", true)
6188 .Default(false))
6189 Tokens[I].int_data[0] = CXToken_Keyword;
6190 }
6191 continue;
6192 }
6193
6194 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6195 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6196 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6197 if (llvm::StringSwitch<bool>(II->getName())
6198 .Case("in", true)
6199 .Case("out", true)
6200 .Case("inout", true)
6201 .Case("oneway", true)
6202 .Case("bycopy", true)
6203 .Case("byref", true)
6204 .Default(false))
6205 Tokens[I].int_data[0] = CXToken_Keyword;
6206 continue;
6207 }
6208
6209 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6210 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6211 Tokens[I].int_data[0] = CXToken_Keyword;
6212 continue;
6213 }
6214 }
6215 }
6216}
6217
6218extern "C" {
6219
6220void clang_annotateTokens(CXTranslationUnit TU,
6221 CXToken *Tokens, unsigned NumTokens,
6222 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006223 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006224 LOG_BAD_TU(TU);
6225 return;
6226 }
6227 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006228 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006229 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006230 }
6231
6232 LOG_FUNC_SECTION {
6233 *Log << TU << ' ';
6234 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6235 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6236 *Log << clang_getRange(bloc, eloc);
6237 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006238
6239 // Any token we don't specifically annotate will have a NULL cursor.
6240 CXCursor C = clang_getNullCursor();
6241 for (unsigned I = 0; I != NumTokens; ++I)
6242 Cursors[I] = C;
6243
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006244 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006245 if (!CXXUnit)
6246 return;
6247
6248 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
6249
6250 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
6251 llvm::CrashRecoveryContext CRC;
6252 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
6253 GetSafetyThreadStackSize() * 2)) {
6254 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6255 }
6256}
6257
6258} // end: extern "C"
6259
6260//===----------------------------------------------------------------------===//
6261// Operations for querying linkage of a cursor.
6262//===----------------------------------------------------------------------===//
6263
6264extern "C" {
6265CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6266 if (!clang_isDeclaration(cursor.kind))
6267 return CXLinkage_Invalid;
6268
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006269 const Decl *D = cxcursor::getCursorDecl(cursor);
6270 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006271 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006272 case NoLinkage:
6273 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006274 case InternalLinkage: return CXLinkage_Internal;
6275 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6276 case ExternalLinkage: return CXLinkage_External;
6277 };
6278
6279 return CXLinkage_Invalid;
6280}
6281} // end: extern "C"
6282
6283//===----------------------------------------------------------------------===//
6284// Operations for querying language of a cursor.
6285//===----------------------------------------------------------------------===//
6286
6287static CXLanguageKind getDeclLanguage(const Decl *D) {
6288 if (!D)
6289 return CXLanguage_C;
6290
6291 switch (D->getKind()) {
6292 default:
6293 break;
6294 case Decl::ImplicitParam:
6295 case Decl::ObjCAtDefsField:
6296 case Decl::ObjCCategory:
6297 case Decl::ObjCCategoryImpl:
6298 case Decl::ObjCCompatibleAlias:
6299 case Decl::ObjCImplementation:
6300 case Decl::ObjCInterface:
6301 case Decl::ObjCIvar:
6302 case Decl::ObjCMethod:
6303 case Decl::ObjCProperty:
6304 case Decl::ObjCPropertyImpl:
6305 case Decl::ObjCProtocol:
6306 return CXLanguage_ObjC;
6307 case Decl::CXXConstructor:
6308 case Decl::CXXConversion:
6309 case Decl::CXXDestructor:
6310 case Decl::CXXMethod:
6311 case Decl::CXXRecord:
6312 case Decl::ClassTemplate:
6313 case Decl::ClassTemplatePartialSpecialization:
6314 case Decl::ClassTemplateSpecialization:
6315 case Decl::Friend:
6316 case Decl::FriendTemplate:
6317 case Decl::FunctionTemplate:
6318 case Decl::LinkageSpec:
6319 case Decl::Namespace:
6320 case Decl::NamespaceAlias:
6321 case Decl::NonTypeTemplateParm:
6322 case Decl::StaticAssert:
6323 case Decl::TemplateTemplateParm:
6324 case Decl::TemplateTypeParm:
6325 case Decl::UnresolvedUsingTypename:
6326 case Decl::UnresolvedUsingValue:
6327 case Decl::Using:
6328 case Decl::UsingDirective:
6329 case Decl::UsingShadow:
6330 return CXLanguage_CPlusPlus;
6331 }
6332
6333 return CXLanguage_C;
6334}
6335
6336extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006337
6338static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6339 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
6340 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00006341
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006342 switch (D->getAvailability()) {
6343 case AR_Available:
6344 case AR_NotYetIntroduced:
6345 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006346 return getCursorAvailabilityForDecl(
6347 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006348 return CXAvailability_Available;
6349
6350 case AR_Deprecated:
6351 return CXAvailability_Deprecated;
6352
6353 case AR_Unavailable:
6354 return CXAvailability_NotAvailable;
6355 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006356
6357 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006358}
6359
Guy Benyei11169dd2012-12-18 14:30:41 +00006360enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6361 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006362 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6363 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006364
6365 return CXAvailability_Available;
6366}
6367
6368static CXVersion convertVersion(VersionTuple In) {
6369 CXVersion Out = { -1, -1, -1 };
6370 if (In.empty())
6371 return Out;
6372
6373 Out.Major = In.getMajor();
6374
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006375 Optional<unsigned> Minor = In.getMinor();
6376 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006377 Out.Minor = *Minor;
6378 else
6379 return Out;
6380
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006381 Optional<unsigned> Subminor = In.getSubminor();
6382 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006383 Out.Subminor = *Subminor;
6384
6385 return Out;
6386}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006387
6388static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6389 int *always_deprecated,
6390 CXString *deprecated_message,
6391 int *always_unavailable,
6392 CXString *unavailable_message,
6393 CXPlatformAvailability *availability,
6394 int availability_size) {
6395 bool HadAvailAttr = false;
6396 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006397 for (auto A : D->attrs()) {
6398 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006399 HadAvailAttr = true;
6400 if (always_deprecated)
6401 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006402 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006403 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006404 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006405 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006406 continue;
6407 }
6408
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006409 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006410 HadAvailAttr = true;
6411 if (always_unavailable)
6412 *always_unavailable = 1;
6413 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006414 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006415 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6416 }
6417 continue;
6418 }
6419
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006420 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006421 HadAvailAttr = true;
6422 if (N < availability_size) {
6423 availability[N].Platform
6424 = cxstring::createDup(Avail->getPlatform()->getName());
6425 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6426 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6427 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6428 availability[N].Unavailable = Avail->getUnavailable();
6429 availability[N].Message = cxstring::createDup(Avail->getMessage());
6430 }
6431 ++N;
6432 }
6433 }
6434
6435 if (!HadAvailAttr)
6436 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6437 return getCursorPlatformAvailabilityForDecl(
6438 cast<Decl>(EnumConst->getDeclContext()),
6439 always_deprecated,
6440 deprecated_message,
6441 always_unavailable,
6442 unavailable_message,
6443 availability,
6444 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006445
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006446 return N;
6447}
6448
Guy Benyei11169dd2012-12-18 14:30:41 +00006449int clang_getCursorPlatformAvailability(CXCursor cursor,
6450 int *always_deprecated,
6451 CXString *deprecated_message,
6452 int *always_unavailable,
6453 CXString *unavailable_message,
6454 CXPlatformAvailability *availability,
6455 int availability_size) {
6456 if (always_deprecated)
6457 *always_deprecated = 0;
6458 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006459 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006460 if (always_unavailable)
6461 *always_unavailable = 0;
6462 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006463 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006464
Guy Benyei11169dd2012-12-18 14:30:41 +00006465 if (!clang_isDeclaration(cursor.kind))
6466 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006467
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006468 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006469 if (!D)
6470 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006471
6472 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6473 deprecated_message,
6474 always_unavailable,
6475 unavailable_message,
6476 availability,
6477 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006478}
6479
6480void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6481 clang_disposeString(availability->Platform);
6482 clang_disposeString(availability->Message);
6483}
6484
6485CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6486 if (clang_isDeclaration(cursor.kind))
6487 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6488
6489 return CXLanguage_Invalid;
6490}
6491
6492 /// \brief If the given cursor is the "templated" declaration
6493 /// descibing a class or function template, return the class or
6494 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006495static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006496 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006497 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006498
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006499 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006500 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6501 return FunTmpl;
6502
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006503 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006504 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6505 return ClassTmpl;
6506
6507 return D;
6508}
6509
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006510
6511enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
6512 StorageClass sc = SC_None;
6513 const Decl *D = getCursorDecl(C);
6514 if (D) {
6515 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
6516 sc = FD->getStorageClass();
6517 } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
6518 sc = VD->getStorageClass();
6519 } else {
6520 return CX_SC_Invalid;
6521 }
6522 } else {
6523 return CX_SC_Invalid;
6524 }
6525 switch (sc) {
6526 case SC_None:
6527 return CX_SC_None;
6528 case SC_Extern:
6529 return CX_SC_Extern;
6530 case SC_Static:
6531 return CX_SC_Static;
6532 case SC_PrivateExtern:
6533 return CX_SC_PrivateExtern;
6534 case SC_OpenCLWorkGroupLocal:
6535 return CX_SC_OpenCLWorkGroupLocal;
6536 case SC_Auto:
6537 return CX_SC_Auto;
6538 case SC_Register:
6539 return CX_SC_Register;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006540 }
Kaelyn Takataab61e702014-10-15 18:03:26 +00006541 llvm_unreachable("Unhandled storage class!");
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006542}
6543
Guy Benyei11169dd2012-12-18 14:30:41 +00006544CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6545 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006546 if (const Decl *D = getCursorDecl(cursor)) {
6547 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006548 if (!DC)
6549 return clang_getNullCursor();
6550
6551 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6552 getCursorTU(cursor));
6553 }
6554 }
6555
6556 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006557 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006558 return MakeCXCursor(D, getCursorTU(cursor));
6559 }
6560
6561 return clang_getNullCursor();
6562}
6563
6564CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6565 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006566 if (const Decl *D = getCursorDecl(cursor)) {
6567 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006568 if (!DC)
6569 return clang_getNullCursor();
6570
6571 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6572 getCursorTU(cursor));
6573 }
6574 }
6575
6576 // FIXME: Note that we can't easily compute the lexical context of a
6577 // statement or expression, so we return nothing.
6578 return clang_getNullCursor();
6579}
6580
6581CXFile clang_getIncludedFile(CXCursor cursor) {
6582 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006583 return nullptr;
6584
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006585 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006586 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006587}
6588
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006589unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6590 if (C.kind != CXCursor_ObjCPropertyDecl)
6591 return CXObjCPropertyAttr_noattr;
6592
6593 unsigned Result = CXObjCPropertyAttr_noattr;
6594 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6595 ObjCPropertyDecl::PropertyAttributeKind Attr =
6596 PD->getPropertyAttributesAsWritten();
6597
6598#define SET_CXOBJCPROP_ATTR(A) \
6599 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6600 Result |= CXObjCPropertyAttr_##A
6601 SET_CXOBJCPROP_ATTR(readonly);
6602 SET_CXOBJCPROP_ATTR(getter);
6603 SET_CXOBJCPROP_ATTR(assign);
6604 SET_CXOBJCPROP_ATTR(readwrite);
6605 SET_CXOBJCPROP_ATTR(retain);
6606 SET_CXOBJCPROP_ATTR(copy);
6607 SET_CXOBJCPROP_ATTR(nonatomic);
6608 SET_CXOBJCPROP_ATTR(setter);
6609 SET_CXOBJCPROP_ATTR(atomic);
6610 SET_CXOBJCPROP_ATTR(weak);
6611 SET_CXOBJCPROP_ATTR(strong);
6612 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6613#undef SET_CXOBJCPROP_ATTR
6614
6615 return Result;
6616}
6617
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006618unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6619 if (!clang_isDeclaration(C.kind))
6620 return CXObjCDeclQualifier_None;
6621
6622 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6623 const Decl *D = getCursorDecl(C);
6624 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6625 QT = MD->getObjCDeclQualifier();
6626 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6627 QT = PD->getObjCDeclQualifier();
6628 if (QT == Decl::OBJC_TQ_None)
6629 return CXObjCDeclQualifier_None;
6630
6631 unsigned Result = CXObjCDeclQualifier_None;
6632 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6633 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6634 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6635 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6636 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6637 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6638
6639 return Result;
6640}
6641
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006642unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6643 if (!clang_isDeclaration(C.kind))
6644 return 0;
6645
6646 const Decl *D = getCursorDecl(C);
6647 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6648 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6649 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6650 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6651
6652 return 0;
6653}
6654
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006655unsigned clang_Cursor_isVariadic(CXCursor C) {
6656 if (!clang_isDeclaration(C.kind))
6657 return 0;
6658
6659 const Decl *D = getCursorDecl(C);
6660 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6661 return FD->isVariadic();
6662 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6663 return MD->isVariadic();
6664
6665 return 0;
6666}
6667
Guy Benyei11169dd2012-12-18 14:30:41 +00006668CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6669 if (!clang_isDeclaration(C.kind))
6670 return clang_getNullRange();
6671
6672 const Decl *D = getCursorDecl(C);
6673 ASTContext &Context = getCursorContext(C);
6674 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6675 if (!RC)
6676 return clang_getNullRange();
6677
6678 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6679}
6680
6681CXString clang_Cursor_getRawCommentText(CXCursor C) {
6682 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006683 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006684
6685 const Decl *D = getCursorDecl(C);
6686 ASTContext &Context = getCursorContext(C);
6687 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6688 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6689 StringRef();
6690
6691 // Don't duplicate the string because RawText points directly into source
6692 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006693 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006694}
6695
6696CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6697 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006698 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006699
6700 const Decl *D = getCursorDecl(C);
6701 const ASTContext &Context = getCursorContext(C);
6702 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6703
6704 if (RC) {
6705 StringRef BriefText = RC->getBriefText(Context);
6706
6707 // Don't duplicate the string because RawComment ensures that this memory
6708 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006709 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006710 }
6711
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006712 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006713}
6714
Guy Benyei11169dd2012-12-18 14:30:41 +00006715CXModule clang_Cursor_getModule(CXCursor C) {
6716 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006717 if (const ImportDecl *ImportD =
6718 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006719 return ImportD->getImportedModule();
6720 }
6721
Craig Topper69186e72014-06-08 08:38:04 +00006722 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006723}
6724
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006725CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6726 if (isNotUsableTU(TU)) {
6727 LOG_BAD_TU(TU);
6728 return nullptr;
6729 }
6730 if (!File)
6731 return nullptr;
6732 FileEntry *FE = static_cast<FileEntry *>(File);
6733
6734 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6735 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6736 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6737
Richard Smithfeb54b62014-10-23 02:01:19 +00006738 return Header.getModule();
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006739}
6740
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006741CXFile clang_Module_getASTFile(CXModule CXMod) {
6742 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006743 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006744 Module *Mod = static_cast<Module*>(CXMod);
6745 return const_cast<FileEntry *>(Mod->getASTFile());
6746}
6747
Guy Benyei11169dd2012-12-18 14:30:41 +00006748CXModule clang_Module_getParent(CXModule CXMod) {
6749 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006750 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006751 Module *Mod = static_cast<Module*>(CXMod);
6752 return Mod->Parent;
6753}
6754
6755CXString clang_Module_getName(CXModule CXMod) {
6756 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006757 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006758 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006759 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006760}
6761
6762CXString clang_Module_getFullName(CXModule CXMod) {
6763 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006764 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006765 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006766 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006767}
6768
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006769int clang_Module_isSystem(CXModule CXMod) {
6770 if (!CXMod)
6771 return 0;
6772 Module *Mod = static_cast<Module*>(CXMod);
6773 return Mod->IsSystem;
6774}
6775
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006776unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6777 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006778 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006779 LOG_BAD_TU(TU);
6780 return 0;
6781 }
6782 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006783 return 0;
6784 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006785 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6786 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6787 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006788}
6789
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006790CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6791 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006792 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006793 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006794 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006795 }
6796 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006797 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006798 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006799 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006800
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006801 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6802 if (Index < TopHeaders.size())
6803 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006804
Craig Topper69186e72014-06-08 08:38:04 +00006805 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006806}
6807
6808} // end: extern "C"
6809
6810//===----------------------------------------------------------------------===//
6811// C++ AST instrospection.
6812//===----------------------------------------------------------------------===//
6813
6814extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006815unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6816 if (!clang_isDeclaration(C.kind))
6817 return 0;
6818
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006819 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006820 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006821 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006822 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6823}
6824
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006825unsigned clang_CXXMethod_isConst(CXCursor C) {
6826 if (!clang_isDeclaration(C.kind))
6827 return 0;
6828
6829 const Decl *D = cxcursor::getCursorDecl(C);
6830 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006831 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006832 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6833}
6834
Guy Benyei11169dd2012-12-18 14:30:41 +00006835unsigned clang_CXXMethod_isStatic(CXCursor C) {
6836 if (!clang_isDeclaration(C.kind))
6837 return 0;
6838
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006839 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006840 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006841 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006842 return (Method && Method->isStatic()) ? 1 : 0;
6843}
6844
6845unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6846 if (!clang_isDeclaration(C.kind))
6847 return 0;
6848
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006849 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006850 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006851 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006852 return (Method && Method->isVirtual()) ? 1 : 0;
6853}
6854} // end: extern "C"
6855
6856//===----------------------------------------------------------------------===//
6857// Attribute introspection.
6858//===----------------------------------------------------------------------===//
6859
6860extern "C" {
6861CXType clang_getIBOutletCollectionType(CXCursor C) {
6862 if (C.kind != CXCursor_IBOutletCollectionAttr)
6863 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6864
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006865 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006866 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6867
6868 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6869}
6870} // end: extern "C"
6871
6872//===----------------------------------------------------------------------===//
6873// Inspecting memory usage.
6874//===----------------------------------------------------------------------===//
6875
6876typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6877
6878static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6879 enum CXTUResourceUsageKind k,
6880 unsigned long amount) {
6881 CXTUResourceUsageEntry entry = { k, amount };
6882 entries.push_back(entry);
6883}
6884
6885extern "C" {
6886
6887const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6888 const char *str = "";
6889 switch (kind) {
6890 case CXTUResourceUsage_AST:
6891 str = "ASTContext: expressions, declarations, and types";
6892 break;
6893 case CXTUResourceUsage_Identifiers:
6894 str = "ASTContext: identifiers";
6895 break;
6896 case CXTUResourceUsage_Selectors:
6897 str = "ASTContext: selectors";
6898 break;
6899 case CXTUResourceUsage_GlobalCompletionResults:
6900 str = "Code completion: cached global results";
6901 break;
6902 case CXTUResourceUsage_SourceManagerContentCache:
6903 str = "SourceManager: content cache allocator";
6904 break;
6905 case CXTUResourceUsage_AST_SideTables:
6906 str = "ASTContext: side tables";
6907 break;
6908 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6909 str = "SourceManager: malloc'ed memory buffers";
6910 break;
6911 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6912 str = "SourceManager: mmap'ed memory buffers";
6913 break;
6914 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6915 str = "ExternalASTSource: malloc'ed memory buffers";
6916 break;
6917 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6918 str = "ExternalASTSource: mmap'ed memory buffers";
6919 break;
6920 case CXTUResourceUsage_Preprocessor:
6921 str = "Preprocessor: malloc'ed memory";
6922 break;
6923 case CXTUResourceUsage_PreprocessingRecord:
6924 str = "Preprocessor: PreprocessingRecord";
6925 break;
6926 case CXTUResourceUsage_SourceManager_DataStructures:
6927 str = "SourceManager: data structures and tables";
6928 break;
6929 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6930 str = "Preprocessor: header search tables";
6931 break;
6932 }
6933 return str;
6934}
6935
6936CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006937 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006938 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006939 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00006940 return usage;
6941 }
6942
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006943 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006944 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006945 ASTContext &astContext = astUnit->getASTContext();
6946
6947 // How much memory is used by AST nodes and types?
6948 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6949 (unsigned long) astContext.getASTAllocatedMemory());
6950
6951 // How much memory is used by identifiers?
6952 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6953 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6954
6955 // How much memory is used for selectors?
6956 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6957 (unsigned long) astContext.Selectors.getTotalMemory());
6958
6959 // How much memory is used by ASTContext's side tables?
6960 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6961 (unsigned long) astContext.getSideTableAllocatedMemory());
6962
6963 // How much memory is used for caching global code completion results?
6964 unsigned long completionBytes = 0;
6965 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00006966 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006967 completionBytes = completionAllocator->getTotalMemory();
6968 }
6969 createCXTUResourceUsageEntry(*entries,
6970 CXTUResourceUsage_GlobalCompletionResults,
6971 completionBytes);
6972
6973 // How much memory is being used by SourceManager's content cache?
6974 createCXTUResourceUsageEntry(*entries,
6975 CXTUResourceUsage_SourceManagerContentCache,
6976 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6977
6978 // How much memory is being used by the MemoryBuffer's in SourceManager?
6979 const SourceManager::MemoryBufferSizes &srcBufs =
6980 astUnit->getSourceManager().getMemoryBufferSizes();
6981
6982 createCXTUResourceUsageEntry(*entries,
6983 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6984 (unsigned long) srcBufs.malloc_bytes);
6985 createCXTUResourceUsageEntry(*entries,
6986 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6987 (unsigned long) srcBufs.mmap_bytes);
6988 createCXTUResourceUsageEntry(*entries,
6989 CXTUResourceUsage_SourceManager_DataStructures,
6990 (unsigned long) astContext.getSourceManager()
6991 .getDataStructureSizes());
6992
6993 // How much memory is being used by the ExternalASTSource?
6994 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6995 const ExternalASTSource::MemoryBufferSizes &sizes =
6996 esrc->getMemoryBufferSizes();
6997
6998 createCXTUResourceUsageEntry(*entries,
6999 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
7000 (unsigned long) sizes.malloc_bytes);
7001 createCXTUResourceUsageEntry(*entries,
7002 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
7003 (unsigned long) sizes.mmap_bytes);
7004 }
7005
7006 // How much memory is being used by the Preprocessor?
7007 Preprocessor &pp = astUnit->getPreprocessor();
7008 createCXTUResourceUsageEntry(*entries,
7009 CXTUResourceUsage_Preprocessor,
7010 pp.getTotalMemory());
7011
7012 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
7013 createCXTUResourceUsageEntry(*entries,
7014 CXTUResourceUsage_PreprocessingRecord,
7015 pRec->getTotalMemory());
7016 }
7017
7018 createCXTUResourceUsageEntry(*entries,
7019 CXTUResourceUsage_Preprocessor_HeaderSearch,
7020 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00007021
Guy Benyei11169dd2012-12-18 14:30:41 +00007022 CXTUResourceUsage usage = { (void*) entries.get(),
7023 (unsigned) entries->size(),
Alexander Kornienko6ee521c2015-01-23 15:36:10 +00007024 !entries->empty() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00007025 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00007026 return usage;
7027}
7028
7029void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
7030 if (usage.data)
7031 delete (MemUsageEntries*) usage.data;
7032}
7033
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007034CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
7035 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007036 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00007037 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007038
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007039 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007040 LOG_BAD_TU(TU);
7041 return skipped;
7042 }
7043
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007044 if (!file)
7045 return skipped;
7046
7047 ASTUnit *astUnit = cxtu::getASTUnit(TU);
7048 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
7049 if (!ppRec)
7050 return skipped;
7051
7052 ASTContext &Ctx = astUnit->getASTContext();
7053 SourceManager &sm = Ctx.getSourceManager();
7054 FileEntry *fileEntry = static_cast<FileEntry *>(file);
7055 FileID wantedFileID = sm.translateFile(fileEntry);
7056
7057 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
7058 std::vector<SourceRange> wantedRanges;
7059 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
7060 i != ei; ++i) {
7061 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
7062 wantedRanges.push_back(*i);
7063 }
7064
7065 skipped->count = wantedRanges.size();
7066 skipped->ranges = new CXSourceRange[skipped->count];
7067 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
7068 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
7069
7070 return skipped;
7071}
7072
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007073void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
7074 if (ranges) {
7075 delete[] ranges->ranges;
7076 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007077 }
7078}
7079
Guy Benyei11169dd2012-12-18 14:30:41 +00007080} // end extern "C"
7081
7082void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
7083 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
7084 for (unsigned I = 0; I != Usage.numEntries; ++I)
7085 fprintf(stderr, " %s: %lu\n",
7086 clang_getTUResourceUsageName(Usage.entries[I].kind),
7087 Usage.entries[I].amount);
7088
7089 clang_disposeCXTUResourceUsage(Usage);
7090}
7091
7092//===----------------------------------------------------------------------===//
7093// Misc. utility functions.
7094//===----------------------------------------------------------------------===//
7095
7096/// Default to using an 8 MB stack size on "safety" threads.
7097static unsigned SafetyStackThreadSize = 8 << 20;
7098
7099namespace clang {
7100
7101bool RunSafely(llvm::CrashRecoveryContext &CRC,
7102 void (*Fn)(void*), void *UserData,
7103 unsigned Size) {
7104 if (!Size)
7105 Size = GetSafetyThreadStackSize();
7106 if (Size)
7107 return CRC.RunSafelyOnThread(Fn, UserData, Size);
7108 return CRC.RunSafely(Fn, UserData);
7109}
7110
7111unsigned GetSafetyThreadStackSize() {
7112 return SafetyStackThreadSize;
7113}
7114
7115void SetSafetyThreadStackSize(unsigned Value) {
7116 SafetyStackThreadSize = Value;
7117}
7118
7119}
7120
7121void clang::setThreadBackgroundPriority() {
7122 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
7123 return;
7124
Alp Toker1a86ad22014-07-06 06:24:00 +00007125#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00007126 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
7127#endif
7128}
7129
7130void cxindex::printDiagsToStderr(ASTUnit *Unit) {
7131 if (!Unit)
7132 return;
7133
7134 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
7135 DEnd = Unit->stored_diag_end();
7136 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00007137 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00007138 CXString Msg = clang_formatDiagnostic(&Diag,
7139 clang_defaultDiagnosticDisplayOptions());
7140 fprintf(stderr, "%s\n", clang_getCString(Msg));
7141 clang_disposeString(Msg);
7142 }
7143#ifdef LLVM_ON_WIN32
7144 // On Windows, force a flush, since there may be multiple copies of
7145 // stderr and stdout in the file system, all with different buffers
7146 // but writing to the same device.
7147 fflush(stderr);
7148#endif
7149}
7150
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007151MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
7152 SourceLocation MacroDefLoc,
7153 CXTranslationUnit TU){
7154 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007155 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007156 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007157 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007158
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007159 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007160 Preprocessor &PP = Unit->getPreprocessor();
Richard Smith20e883e2015-04-29 23:20:19 +00007161 MacroDirective *MD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007162 if (MD) {
7163 for (MacroDirective::DefInfo
7164 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
7165 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
7166 return Def.getMacroInfo();
7167 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007168 }
7169
Craig Topper69186e72014-06-08 08:38:04 +00007170 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007171}
7172
Richard Smith66a81862015-05-04 02:25:31 +00007173const MacroInfo *cxindex::getMacroInfo(const MacroDefinitionRecord *MacroDef,
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007174 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007175 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007176 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007177 const IdentifierInfo *II = MacroDef->getName();
7178 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00007179 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007180
7181 return getMacroInfo(*II, MacroDef->getLocation(), TU);
7182}
7183
Richard Smith66a81862015-05-04 02:25:31 +00007184MacroDefinitionRecord *
7185cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, const Token &Tok,
7186 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007187 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007188 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007189 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00007190 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007191
7192 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007193 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007194 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
7195 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007196 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007197
7198 // Check that the token is inside the definition and not its argument list.
7199 SourceManager &SM = Unit->getSourceManager();
7200 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00007201 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007202 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00007203 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007204
7205 Preprocessor &PP = Unit->getPreprocessor();
7206 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
7207 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00007208 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007209
Alp Toker2d57cea2014-05-17 04:53:25 +00007210 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007211 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007212 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007213
7214 // Check that the identifier is not one of the macro arguments.
7215 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00007216 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007217
Richard Smith20e883e2015-04-29 23:20:19 +00007218 MacroDirective *InnerMD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007219 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00007220 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007221
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007222 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007223}
7224
Richard Smith66a81862015-05-04 02:25:31 +00007225MacroDefinitionRecord *
7226cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, SourceLocation Loc,
7227 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007228 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007229 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007230
7231 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007232 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007233 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007234 Preprocessor &PP = Unit->getPreprocessor();
7235 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00007236 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007237 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7238 Token Tok;
7239 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00007240 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007241
7242 return checkForMacroInMacroDefinition(MI, Tok, TU);
7243}
7244
Guy Benyei11169dd2012-12-18 14:30:41 +00007245extern "C" {
7246
7247CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007248 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00007249}
7250
7251} // end: extern "C"
7252
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007253Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7254 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007255 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007256 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007257 if (Unit->isMainFileAST())
7258 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007259 return *this;
7260 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007261 } else {
7262 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007263 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007264 return *this;
7265}
7266
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007267Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7268 *this << FE->getName();
7269 return *this;
7270}
7271
7272Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7273 CXString cursorName = clang_getCursorDisplayName(cursor);
7274 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7275 clang_disposeString(cursorName);
7276 return *this;
7277}
7278
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007279Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7280 CXFile File;
7281 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007282 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007283 CXString FileName = clang_getFileName(File);
7284 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7285 clang_disposeString(FileName);
7286 return *this;
7287}
7288
7289Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7290 CXSourceLocation BLoc = clang_getRangeStart(range);
7291 CXSourceLocation ELoc = clang_getRangeEnd(range);
7292
7293 CXFile BFile;
7294 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007295 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007296
7297 CXFile EFile;
7298 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007299 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007300
7301 CXString BFileName = clang_getFileName(BFile);
7302 if (BFile == EFile) {
7303 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7304 BLine, BColumn, ELine, EColumn);
7305 } else {
7306 CXString EFileName = clang_getFileName(EFile);
7307 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7308 BLine, BColumn)
7309 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7310 ELine, EColumn);
7311 clang_disposeString(EFileName);
7312 }
7313 clang_disposeString(BFileName);
7314 return *this;
7315}
7316
7317Logger &cxindex::Logger::operator<<(CXString Str) {
7318 *this << clang_getCString(Str);
7319 return *this;
7320}
7321
7322Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7323 LogOS << Fmt;
7324 return *this;
7325}
7326
Chandler Carruth37ad2582014-06-27 15:14:39 +00007327static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7328
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007329cxindex::Logger::~Logger() {
7330 LogOS.flush();
7331
Chandler Carruth37ad2582014-06-27 15:14:39 +00007332 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007333
7334 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7335
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007336 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007337 OS << "[libclang:" << Name << ':';
7338
Alp Toker1a86ad22014-07-06 06:24:00 +00007339#ifdef USE_DARWIN_THREADS
7340 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007341 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7342 OS << tid << ':';
7343#endif
7344
7345 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7346 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
Yaron Keren09fb7c62015-03-10 07:33:23 +00007347 OS << Msg << '\n';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007348
7349 if (Trace) {
Zachary Turner1fe2a8d2015-03-05 19:15:09 +00007350 llvm::sys::PrintStackTrace(OS);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007351 OS << "--------------------------------------------------\n";
7352 }
7353}