blob: 1b41e0066f575f039a2c16d81392fd6ed4a3742d [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;
457
458 continue;
459 }
460
461 if (MacroDefinition *MD = dyn_cast<MacroDefinition>(PPE)) {
462 if (Visit(MakeMacroDefinitionCursor(MD, TU)))
463 return true;
464
465 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);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000571 if (MacroDefinition *MacroDef =
572 checkForMacroInMacroDefinition(MI, Loc, TU))
573 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]); }
Guy Benyei11169dd2012-12-18 14:30:41 +00001721 bool isFirst() const { return data[1] ? true : false; }
1722};
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 Bataev6125da92014-07-21 11:26:11 +00001882 void VisitOMPFlushDirective(const OMPFlushDirective *D);
Alexey Bataev9fb6e642014-07-22 06:45:04 +00001883 void VisitOMPOrderedDirective(const OMPOrderedDirective *D);
Alexey Bataev0162e452014-07-22 10:10:35 +00001884 void VisitOMPAtomicDirective(const OMPAtomicDirective *D);
Alexey Bataev0bd520b2014-09-19 08:19:49 +00001885 void VisitOMPTargetDirective(const OMPTargetDirective *D);
Alexey Bataev13314bf2014-10-09 04:18:56 +00001886 void VisitOMPTeamsDirective(const OMPTeamsDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001887
Guy Benyei11169dd2012-12-18 14:30:41 +00001888private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001889 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001890 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1891 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001892 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1893 void AddStmt(const Stmt *S);
1894 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001895 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001896 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001897 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001898};
1899} // end anonyous namespace
1900
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001901void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001902 // 'S' should always be non-null, since it comes from the
1903 // statement we are visiting.
1904 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1905}
1906
1907void
1908EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1909 if (Qualifier)
1910 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1911}
1912
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001913void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001914 if (S)
1915 WL.push_back(StmtVisit(S, Parent));
1916}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001917void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001918 if (D)
1919 WL.push_back(DeclVisit(D, Parent, isFirst));
1920}
1921void EnqueueVisitor::
1922 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1923 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001924 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001925}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001926void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001927 if (D)
1928 WL.push_back(MemberRefVisit(D, L, Parent));
1929}
1930void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1931 if (TI)
1932 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1933 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001934void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001935 unsigned size = WL.size();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001936 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001937 AddStmt(*Child);
1938 }
1939 if (size == WL.size())
1940 return;
1941 // Now reverse the entries we just added. This will match the DFS
1942 // ordering performed by the worklist.
1943 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1944 std::reverse(I, E);
1945}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001946namespace {
1947class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1948 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001949 /// \brief Process clauses with list of variables.
1950 template <typename T>
1951 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001952public:
1953 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1954#define OPENMP_CLAUSE(Name, Class) \
1955 void Visit##Class(const Class *C);
1956#include "clang/Basic/OpenMPKinds.def"
1957};
1958
Alexey Bataevaadd52e2014-02-13 05:29:23 +00001959void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
1960 Visitor->AddStmt(C->getCondition());
1961}
1962
Alexey Bataev3778b602014-07-17 07:32:53 +00001963void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
1964 Visitor->AddStmt(C->getCondition());
1965}
1966
Alexey Bataev568a8332014-03-06 06:15:19 +00001967void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
1968 Visitor->AddStmt(C->getNumThreads());
1969}
1970
Alexey Bataev62c87d22014-03-21 04:51:18 +00001971void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
1972 Visitor->AddStmt(C->getSafelen());
1973}
1974
Alexander Musman8bd31e62014-05-27 15:12:19 +00001975void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
1976 Visitor->AddStmt(C->getNumForLoops());
1977}
1978
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001979void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00001980
Alexey Bataevbcbadb62014-05-06 06:04:14 +00001981void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
1982
Alexey Bataev56dafe82014-06-20 07:16:17 +00001983void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
1984 Visitor->AddStmt(C->getChunkSize());
1985}
1986
Alexey Bataev142e1fc2014-06-20 09:44:06 +00001987void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *) {}
1988
Alexey Bataev236070f2014-06-20 11:19:47 +00001989void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
1990
Alexey Bataev7aea99a2014-07-17 12:19:31 +00001991void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
1992
Alexey Bataev74ba3a52014-07-17 12:47:03 +00001993void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
1994
Alexey Bataevf98b00c2014-07-23 02:27:21 +00001995void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}
1996
Alexey Bataevdea47612014-07-23 07:46:59 +00001997void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {}
1998
Alexey Bataev67a4f222014-07-23 10:25:33 +00001999void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {}
2000
Alexey Bataev459dec02014-07-24 06:46:57 +00002001void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}
2002
Alexey Bataev82bad8b2014-07-24 08:55:34 +00002003void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
2004
Alexey Bataev756c1962013-09-24 03:17:45 +00002005template<typename T>
2006void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Alexey Bataev03b340a2014-10-21 03:16:40 +00002007 for (const auto *I : Node->varlists()) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00002008 Visitor->AddStmt(I);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002009 }
Alexey Bataev756c1962013-09-24 03:17:45 +00002010}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002011
2012void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002013 VisitOMPClauseList(C);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002014 for (const auto *E : C->private_copies()) {
2015 Visitor->AddStmt(E);
2016 }
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002017}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002018void OMPClauseEnqueue::VisitOMPFirstprivateClause(
2019 const OMPFirstprivateClause *C) {
2020 VisitOMPClauseList(C);
2021}
Alexander Musman1bb328c2014-06-04 13:06:39 +00002022void OMPClauseEnqueue::VisitOMPLastprivateClause(
2023 const OMPLastprivateClause *C) {
2024 VisitOMPClauseList(C);
2025}
Alexey Bataev758e55e2013-09-06 18:03:48 +00002026void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002027 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00002028}
Alexey Bataevc5e02582014-06-16 07:08:35 +00002029void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
2030 VisitOMPClauseList(C);
2031}
Alexander Musman8dba6642014-04-22 13:09:42 +00002032void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2033 VisitOMPClauseList(C);
2034 Visitor->AddStmt(C->getStep());
2035}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002036void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2037 VisitOMPClauseList(C);
2038 Visitor->AddStmt(C->getAlignment());
2039}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002040void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2041 VisitOMPClauseList(C);
2042}
Alexey Bataevbae9a792014-06-27 10:37:06 +00002043void
2044OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
2045 VisitOMPClauseList(C);
2046}
Alexey Bataev6125da92014-07-21 11:26:11 +00002047void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2048 VisitOMPClauseList(C);
2049}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002050}
Alexey Bataev756c1962013-09-24 03:17:45 +00002051
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002052void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2053 unsigned size = WL.size();
2054 OMPClauseEnqueue Visitor(this);
2055 Visitor.Visit(S);
2056 if (size == WL.size())
2057 return;
2058 // Now reverse the entries we just added. This will match the DFS
2059 // ordering performed by the worklist.
2060 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2061 std::reverse(I, E);
2062}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002063void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002064 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2065}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002066void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002067 AddDecl(B->getBlockDecl());
2068}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002069void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002070 EnqueueChildren(E);
2071 AddTypeLoc(E->getTypeSourceInfo());
2072}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002073void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
2074 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00002075 E = S->body_rend(); I != E; ++I) {
2076 AddStmt(*I);
2077 }
2078}
2079void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002080VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002081 AddStmt(S->getSubStmt());
2082 AddDeclarationNameInfo(S);
2083 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2084 AddNestedNameSpecifierLoc(QualifierLoc);
2085}
2086
2087void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002088VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002089 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2090 AddDeclarationNameInfo(E);
2091 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2092 AddNestedNameSpecifierLoc(QualifierLoc);
2093 if (!E->isImplicitAccess())
2094 AddStmt(E->getBase());
2095}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002096void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002097 // Enqueue the initializer , if any.
2098 AddStmt(E->getInitializer());
2099 // Enqueue the array size, if any.
2100 AddStmt(E->getArraySize());
2101 // Enqueue the allocated type.
2102 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2103 // Enqueue the placement arguments.
2104 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2105 AddStmt(E->getPlacementArg(I-1));
2106}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002107void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002108 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2109 AddStmt(CE->getArg(I-1));
2110 AddStmt(CE->getCallee());
2111 AddStmt(CE->getArg(0));
2112}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002113void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2114 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002115 // Visit the name of the type being destroyed.
2116 AddTypeLoc(E->getDestroyedTypeInfo());
2117 // Visit the scope type that looks disturbingly like the nested-name-specifier
2118 // but isn't.
2119 AddTypeLoc(E->getScopeTypeInfo());
2120 // Visit the nested-name-specifier.
2121 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2122 AddNestedNameSpecifierLoc(QualifierLoc);
2123 // Visit base expression.
2124 AddStmt(E->getBase());
2125}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002126void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2127 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002128 AddTypeLoc(E->getTypeSourceInfo());
2129}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002130void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2131 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002132 EnqueueChildren(E);
2133 AddTypeLoc(E->getTypeSourceInfo());
2134}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002135void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002136 EnqueueChildren(E);
2137 if (E->isTypeOperand())
2138 AddTypeLoc(E->getTypeOperandSourceInfo());
2139}
2140
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002141void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2142 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002143 EnqueueChildren(E);
2144 AddTypeLoc(E->getTypeSourceInfo());
2145}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002146void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002147 EnqueueChildren(E);
2148 if (E->isTypeOperand())
2149 AddTypeLoc(E->getTypeOperandSourceInfo());
2150}
2151
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002152void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002153 EnqueueChildren(S);
2154 AddDecl(S->getExceptionDecl());
2155}
2156
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002157void EnqueueVisitor::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002158 AddStmt(S->getBody());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002159 AddStmt(S->getRangeInit());
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002160 AddDecl(S->getLoopVariable());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002161}
2162
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002163void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002164 if (DR->hasExplicitTemplateArgs()) {
2165 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2166 }
2167 WL.push_back(DeclRefExprParts(DR, Parent));
2168}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002169void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2170 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002171 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2172 AddDeclarationNameInfo(E);
2173 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2174}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002175void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002176 unsigned size = WL.size();
2177 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002178 for (const auto *D : S->decls()) {
2179 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002180 isFirst = false;
2181 }
2182 if (size == WL.size())
2183 return;
2184 // Now reverse the entries we just added. This will match the DFS
2185 // ordering performed by the worklist.
2186 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2187 std::reverse(I, E);
2188}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002189void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002190 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002191 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002192 D = E->designators_rbegin(), DEnd = E->designators_rend();
2193 D != DEnd; ++D) {
2194 if (D->isFieldDesignator()) {
2195 if (FieldDecl *Field = D->getField())
2196 AddMemberRef(Field, D->getFieldLoc());
2197 continue;
2198 }
2199 if (D->isArrayDesignator()) {
2200 AddStmt(E->getArrayIndex(*D));
2201 continue;
2202 }
2203 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2204 AddStmt(E->getArrayRangeEnd(*D));
2205 AddStmt(E->getArrayRangeStart(*D));
2206 }
2207}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002208void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002209 EnqueueChildren(E);
2210 AddTypeLoc(E->getTypeInfoAsWritten());
2211}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002212void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002213 AddStmt(FS->getBody());
2214 AddStmt(FS->getInc());
2215 AddStmt(FS->getCond());
2216 AddDecl(FS->getConditionVariable());
2217 AddStmt(FS->getInit());
2218}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002219void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002220 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2221}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002222void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002223 AddStmt(If->getElse());
2224 AddStmt(If->getThen());
2225 AddStmt(If->getCond());
2226 AddDecl(If->getConditionVariable());
2227}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002228void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002229 // We care about the syntactic form of the initializer list, only.
2230 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2231 IE = Syntactic;
2232 EnqueueChildren(IE);
2233}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002234void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002235 WL.push_back(MemberExprParts(M, Parent));
2236
2237 // If the base of the member access expression is an implicit 'this', don't
2238 // visit it.
2239 // FIXME: If we ever want to show these implicit accesses, this will be
2240 // unfortunate. However, clang_getCursor() relies on this behavior.
Argyrios Kyrtzidis58d0e7a2015-03-13 04:40:07 +00002241 if (M->isImplicitAccess())
2242 return;
2243
2244 // Ignore base anonymous struct/union fields, otherwise they will shadow the
2245 // real field that that we are interested in.
2246 if (auto *SubME = dyn_cast<MemberExpr>(M->getBase())) {
2247 if (auto *FD = dyn_cast_or_null<FieldDecl>(SubME->getMemberDecl())) {
2248 if (FD->isAnonymousStructOrUnion()) {
2249 AddStmt(SubME->getBase());
2250 return;
2251 }
2252 }
2253 }
2254
2255 AddStmt(M->getBase());
Guy Benyei11169dd2012-12-18 14:30:41 +00002256}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002257void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002258 AddTypeLoc(E->getEncodedTypeSourceInfo());
2259}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002260void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002261 EnqueueChildren(M);
2262 AddTypeLoc(M->getClassReceiverTypeInfo());
2263}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002264void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002265 // Visit the components of the offsetof expression.
2266 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2267 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2268 const OffsetOfNode &Node = E->getComponent(I-1);
2269 switch (Node.getKind()) {
2270 case OffsetOfNode::Array:
2271 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2272 break;
2273 case OffsetOfNode::Field:
2274 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2275 break;
2276 case OffsetOfNode::Identifier:
2277 case OffsetOfNode::Base:
2278 continue;
2279 }
2280 }
2281 // Visit the type into which we're computing the offset.
2282 AddTypeLoc(E->getTypeSourceInfo());
2283}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002284void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002285 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2286 WL.push_back(OverloadExprParts(E, Parent));
2287}
2288void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002289 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002290 EnqueueChildren(E);
2291 if (E->isArgumentType())
2292 AddTypeLoc(E->getArgumentTypeInfo());
2293}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002294void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002295 EnqueueChildren(S);
2296}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002297void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002298 AddStmt(S->getBody());
2299 AddStmt(S->getCond());
2300 AddDecl(S->getConditionVariable());
2301}
2302
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002303void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002304 AddStmt(W->getBody());
2305 AddStmt(W->getCond());
2306 AddDecl(W->getConditionVariable());
2307}
2308
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002309void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002310 for (unsigned I = E->getNumArgs(); I > 0; --I)
2311 AddTypeLoc(E->getArg(I-1));
2312}
2313
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002314void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002315 AddTypeLoc(E->getQueriedTypeSourceInfo());
2316}
2317
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002318void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002319 EnqueueChildren(E);
2320}
2321
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002322void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002323 VisitOverloadExpr(U);
2324 if (!U->isImplicitAccess())
2325 AddStmt(U->getBase());
2326}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002327void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002328 AddStmt(E->getSubExpr());
2329 AddTypeLoc(E->getWrittenTypeInfo());
2330}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002331void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002332 WL.push_back(SizeOfPackExprParts(E, Parent));
2333}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002334void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002335 // If the opaque value has a source expression, just transparently
2336 // visit that. This is useful for (e.g.) pseudo-object expressions.
2337 if (Expr *SourceExpr = E->getSourceExpr())
2338 return Visit(SourceExpr);
2339}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002340void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002341 AddStmt(E->getBody());
2342 WL.push_back(LambdaExprParts(E, Parent));
2343}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002344void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002345 // Treat the expression like its syntactic form.
2346 Visit(E->getSyntacticForm());
2347}
2348
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002349void EnqueueVisitor::VisitOMPExecutableDirective(
2350 const OMPExecutableDirective *D) {
2351 EnqueueChildren(D);
2352 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2353 E = D->clauses().end();
2354 I != E; ++I)
2355 EnqueueChildren(*I);
2356}
2357
Alexander Musman3aaab662014-08-19 11:27:13 +00002358void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
2359 VisitOMPExecutableDirective(D);
2360}
2361
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002362void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2363 VisitOMPExecutableDirective(D);
2364}
2365
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002366void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002367 VisitOMPLoopDirective(D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002368}
2369
Alexey Bataevf29276e2014-06-18 04:14:57 +00002370void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002371 VisitOMPLoopDirective(D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002372}
2373
Alexander Musmanf82886e2014-09-18 05:12:34 +00002374void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
2375 VisitOMPLoopDirective(D);
2376}
2377
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002378void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2379 VisitOMPExecutableDirective(D);
2380}
2381
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002382void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2383 VisitOMPExecutableDirective(D);
2384}
2385
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002386void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2387 VisitOMPExecutableDirective(D);
2388}
2389
Alexander Musman80c22892014-07-17 08:54:58 +00002390void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2391 VisitOMPExecutableDirective(D);
2392}
2393
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002394void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2395 VisitOMPExecutableDirective(D);
2396 AddDeclarationNameInfo(D);
2397}
2398
Alexey Bataev4acb8592014-07-07 13:01:15 +00002399void
2400EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002401 VisitOMPLoopDirective(D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002402}
2403
Alexander Musmane4e893b2014-09-23 09:33:00 +00002404void EnqueueVisitor::VisitOMPParallelForSimdDirective(
2405 const OMPParallelForSimdDirective *D) {
2406 VisitOMPLoopDirective(D);
2407}
2408
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002409void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2410 const OMPParallelSectionsDirective *D) {
2411 VisitOMPExecutableDirective(D);
2412}
2413
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002414void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2415 VisitOMPExecutableDirective(D);
2416}
2417
Alexey Bataev68446b72014-07-18 07:47:19 +00002418void
2419EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2420 VisitOMPExecutableDirective(D);
2421}
2422
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002423void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2424 VisitOMPExecutableDirective(D);
2425}
2426
Alexey Bataev2df347a2014-07-18 10:17:07 +00002427void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2428 VisitOMPExecutableDirective(D);
2429}
2430
Alexey Bataev6125da92014-07-21 11:26:11 +00002431void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2432 VisitOMPExecutableDirective(D);
2433}
2434
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002435void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2436 VisitOMPExecutableDirective(D);
2437}
2438
Alexey Bataev0162e452014-07-22 10:10:35 +00002439void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2440 VisitOMPExecutableDirective(D);
2441}
2442
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002443void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
2444 VisitOMPExecutableDirective(D);
2445}
2446
Alexey Bataev13314bf2014-10-09 04:18:56 +00002447void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {
2448 VisitOMPExecutableDirective(D);
2449}
2450
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002451void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002452 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2453}
2454
2455bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2456 if (RegionOfInterest.isValid()) {
2457 SourceRange Range = getRawCursorExtent(C);
2458 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2459 return false;
2460 }
2461 return true;
2462}
2463
2464bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2465 while (!WL.empty()) {
2466 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002467 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002468
2469 // Set the Parent field, then back to its old value once we're done.
2470 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2471
2472 switch (LI.getKind()) {
2473 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002474 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002475 if (!D)
2476 continue;
2477
2478 // For now, perform default visitation for Decls.
2479 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2480 cast<DeclVisit>(&LI)->isFirst())))
2481 return true;
2482
2483 continue;
2484 }
2485 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2486 const ASTTemplateArgumentListInfo *ArgList =
2487 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2488 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2489 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2490 Arg != ArgEnd; ++Arg) {
2491 if (VisitTemplateArgumentLoc(*Arg))
2492 return true;
2493 }
2494 continue;
2495 }
2496 case VisitorJob::TypeLocVisitKind: {
2497 // Perform default visitation for TypeLocs.
2498 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2499 return true;
2500 continue;
2501 }
2502 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002503 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002504 if (LabelStmt *stmt = LS->getStmt()) {
2505 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2506 TU))) {
2507 return true;
2508 }
2509 }
2510 continue;
2511 }
2512
2513 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2514 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2515 if (VisitNestedNameSpecifierLoc(V->get()))
2516 return true;
2517 continue;
2518 }
2519
2520 case VisitorJob::DeclarationNameInfoVisitKind: {
2521 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2522 ->get()))
2523 return true;
2524 continue;
2525 }
2526 case VisitorJob::MemberRefVisitKind: {
2527 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2528 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2529 return true;
2530 continue;
2531 }
2532 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002533 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002534 if (!S)
2535 continue;
2536
2537 // Update the current cursor.
2538 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2539 if (!IsInRegionOfInterest(Cursor))
2540 continue;
2541 switch (Visitor(Cursor, Parent, ClientData)) {
2542 case CXChildVisit_Break: return true;
2543 case CXChildVisit_Continue: break;
2544 case CXChildVisit_Recurse:
2545 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002546 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002547 EnqueueWorkList(WL, S);
2548 break;
2549 }
2550 continue;
2551 }
2552 case VisitorJob::MemberExprPartsKind: {
2553 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002554 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002555
2556 // Visit the nested-name-specifier
2557 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2558 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2559 return true;
2560
2561 // Visit the declaration name.
2562 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2563 return true;
2564
2565 // Visit the explicitly-specified template arguments, if any.
2566 if (M->hasExplicitTemplateArgs()) {
2567 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2568 *ArgEnd = Arg + M->getNumTemplateArgs();
2569 Arg != ArgEnd; ++Arg) {
2570 if (VisitTemplateArgumentLoc(*Arg))
2571 return true;
2572 }
2573 }
2574 continue;
2575 }
2576 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002577 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002578 // Visit nested-name-specifier, if present.
2579 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2580 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2581 return true;
2582 // Visit declaration name.
2583 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2584 return true;
2585 continue;
2586 }
2587 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002588 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002589 // Visit the nested-name-specifier.
2590 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2591 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2592 return true;
2593 // Visit the declaration name.
2594 if (VisitDeclarationNameInfo(O->getNameInfo()))
2595 return true;
2596 // Visit the overloaded declaration reference.
2597 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2598 return true;
2599 continue;
2600 }
2601 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002602 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002603 NamedDecl *Pack = E->getPack();
2604 if (isa<TemplateTypeParmDecl>(Pack)) {
2605 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2606 E->getPackLoc(), TU)))
2607 return true;
2608
2609 continue;
2610 }
2611
2612 if (isa<TemplateTemplateParmDecl>(Pack)) {
2613 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2614 E->getPackLoc(), TU)))
2615 return true;
2616
2617 continue;
2618 }
2619
2620 // Non-type template parameter packs and function parameter packs are
2621 // treated like DeclRefExpr cursors.
2622 continue;
2623 }
2624
2625 case VisitorJob::LambdaExprPartsKind: {
2626 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002627 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002628 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2629 CEnd = E->explicit_capture_end();
2630 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002631 // FIXME: Lambda init-captures.
2632 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002633 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002634
Guy Benyei11169dd2012-12-18 14:30:41 +00002635 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2636 C->getLocation(),
2637 TU)))
2638 return true;
2639 }
2640
2641 // Visit parameters and return type, if present.
2642 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2643 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2644 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2645 // Visit the whole type.
2646 if (Visit(TL))
2647 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002648 } else if (FunctionProtoTypeLoc Proto =
2649 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002650 if (E->hasExplicitParameters()) {
2651 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002652 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2653 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002654 return true;
2655 } else {
2656 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002657 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002658 return true;
2659 }
2660 }
2661 }
2662 break;
2663 }
2664
2665 case VisitorJob::PostChildrenVisitKind:
2666 if (PostChildrenVisitor(Parent, ClientData))
2667 return true;
2668 break;
2669 }
2670 }
2671 return false;
2672}
2673
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002674bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002675 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002676 if (!WorkListFreeList.empty()) {
2677 WL = WorkListFreeList.back();
2678 WL->clear();
2679 WorkListFreeList.pop_back();
2680 }
2681 else {
2682 WL = new VisitorWorkList();
2683 WorkListCache.push_back(WL);
2684 }
2685 EnqueueWorkList(*WL, S);
2686 bool result = RunVisitorWorkList(*WL);
2687 WorkListFreeList.push_back(WL);
2688 return result;
2689}
2690
2691namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002692typedef SmallVector<SourceRange, 4> RefNamePieces;
Craig Topper69186e72014-06-08 08:38:04 +00002693RefNamePieces
2694buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2695 const DeclarationNameInfo &NI, const SourceRange &QLoc,
2696 const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002697 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2698 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2699 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2700
2701 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2702
2703 RefNamePieces Pieces;
2704
2705 if (WantQualifier && QLoc.isValid())
2706 Pieces.push_back(QLoc);
2707
2708 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2709 Pieces.push_back(NI.getLoc());
2710
2711 if (WantTemplateArgs && TemplateArgs)
2712 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2713 TemplateArgs->RAngleLoc));
2714
2715 if (Kind == DeclarationName::CXXOperatorName) {
2716 Pieces.push_back(SourceLocation::getFromRawEncoding(
2717 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2718 Pieces.push_back(SourceLocation::getFromRawEncoding(
2719 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2720 }
2721
2722 if (WantSinglePiece) {
2723 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2724 Pieces.clear();
2725 Pieces.push_back(R);
2726 }
2727
2728 return Pieces;
2729}
2730}
2731
2732//===----------------------------------------------------------------------===//
2733// Misc. API hooks.
2734//===----------------------------------------------------------------------===//
2735
Chad Rosier05c71aa2013-03-27 18:28:23 +00002736static void fatal_error_handler(void *user_data, const std::string& reason,
2737 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002738 // Write the result out to stderr avoiding errs() because raw_ostreams can
2739 // call report_fatal_error.
2740 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2741 ::abort();
2742}
2743
Chandler Carruth66660742014-06-27 16:37:27 +00002744namespace {
2745struct RegisterFatalErrorHandler {
2746 RegisterFatalErrorHandler() {
2747 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2748 }
2749};
2750}
2751
2752static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
2753
Guy Benyei11169dd2012-12-18 14:30:41 +00002754extern "C" {
2755CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2756 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002757 // We use crash recovery to make some of our APIs more reliable, implicitly
2758 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002759 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2760 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002761
Chandler Carruth66660742014-06-27 16:37:27 +00002762 // Look through the managed static to trigger construction of the managed
2763 // static which registers our fatal error handler. This ensures it is only
2764 // registered once.
2765 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00002766
2767 CIndexer *CIdxr = new CIndexer();
2768 if (excludeDeclarationsFromPCH)
2769 CIdxr->setOnlyLocalDecls();
2770 if (displayDiagnostics)
2771 CIdxr->setDisplayDiagnostics();
2772
2773 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2774 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2775 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2776 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2777 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2778 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2779
2780 return CIdxr;
2781}
2782
2783void clang_disposeIndex(CXIndex CIdx) {
2784 if (CIdx)
2785 delete static_cast<CIndexer *>(CIdx);
2786}
2787
2788void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2789 if (CIdx)
2790 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2791}
2792
2793unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2794 if (CIdx)
2795 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2796 return 0;
2797}
2798
2799void clang_toggleCrashRecovery(unsigned isEnabled) {
2800 if (isEnabled)
2801 llvm::CrashRecoveryContext::Enable();
2802 else
2803 llvm::CrashRecoveryContext::Disable();
2804}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002805
Guy Benyei11169dd2012-12-18 14:30:41 +00002806CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2807 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002808 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002809 enum CXErrorCode Result =
2810 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002811 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002812 assert((TU && Result == CXError_Success) ||
2813 (!TU && Result != CXError_Success));
2814 return TU;
2815}
2816
2817enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2818 const char *ast_filename,
2819 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002820 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002821 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002822
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002823 if (!CIdx || !ast_filename || !out_TU)
2824 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002825
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002826 LOG_FUNC_SECTION {
2827 *Log << ast_filename;
2828 }
2829
Guy Benyei11169dd2012-12-18 14:30:41 +00002830 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2831 FileSystemOptions FileSystemOpts;
2832
Justin Bognerd512c1e2014-10-15 00:33:06 +00002833 IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
2834 CompilerInstance::createDiagnostics(new DiagnosticOptions());
David Blaikie6f7382d2014-08-10 19:08:04 +00002835 std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
2836 ast_filename, Diags, FileSystemOpts, CXXIdx->getOnlyLocalDecls(), None,
2837 /*CaptureDiagnostics=*/true,
2838 /*AllowPCHWithCompilerErrors=*/true,
2839 /*UserFilesAreVolatile=*/true);
2840 *out_TU = MakeCXTranslationUnit(CXXIdx, AU.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002841 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002842}
2843
2844unsigned clang_defaultEditingTranslationUnitOptions() {
2845 return CXTranslationUnit_PrecompiledPreamble |
2846 CXTranslationUnit_CacheCompletionResults;
2847}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002848
Guy Benyei11169dd2012-12-18 14:30:41 +00002849CXTranslationUnit
2850clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2851 const char *source_filename,
2852 int num_command_line_args,
2853 const char * const *command_line_args,
2854 unsigned num_unsaved_files,
2855 struct CXUnsavedFile *unsaved_files) {
2856 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2857 return clang_parseTranslationUnit(CIdx, source_filename,
2858 command_line_args, num_command_line_args,
2859 unsaved_files, num_unsaved_files,
2860 Options);
2861}
2862
2863struct ParseTranslationUnitInfo {
2864 CXIndex CIdx;
2865 const char *source_filename;
2866 const char *const *command_line_args;
2867 int num_command_line_args;
Alp Toker9d85b182014-07-07 01:23:14 +00002868 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00002869 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002870 CXTranslationUnit *out_TU;
Alp Toker5c532982014-07-07 22:42:03 +00002871 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002872};
2873static void clang_parseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00002874 const ParseTranslationUnitInfo *PTUI =
2875 static_cast<ParseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00002876 CXIndex CIdx = PTUI->CIdx;
2877 const char *source_filename = PTUI->source_filename;
2878 const char * const *command_line_args = PTUI->command_line_args;
2879 int num_command_line_args = PTUI->num_command_line_args;
Guy Benyei11169dd2012-12-18 14:30:41 +00002880 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002881 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002882
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002883 // Set up the initial return values.
2884 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002885 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002886
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002887 // Check arguments.
Alp Toker9d85b182014-07-07 01:23:14 +00002888 if (!CIdx || !out_TU) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002889 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002890 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002891 }
2892
Guy Benyei11169dd2012-12-18 14:30:41 +00002893 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2894
2895 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2896 setThreadBackgroundPriority();
2897
2898 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2899 // FIXME: Add a flag for modules.
2900 TranslationUnitKind TUKind
2901 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002902 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002903 = options & CXTranslationUnit_CacheCompletionResults;
2904 bool IncludeBriefCommentsInCodeCompletion
2905 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2906 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2907 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2908
2909 // Configure the diagnostics.
2910 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002911 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002912
2913 // Recover resources if we crash before exiting this function.
2914 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2915 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00002916 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00002917
Ahmed Charlesb8984322014-03-07 20:03:18 +00002918 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
2919 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002920
2921 // Recover resources if we crash before exiting this function.
2922 llvm::CrashRecoveryContextCleanupRegistrar<
2923 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2924
Alp Toker9d85b182014-07-07 01:23:14 +00002925 for (auto &UF : PTUI->unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00002926 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00002927 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00002928 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00002929 }
2930
Ahmed Charlesb8984322014-03-07 20:03:18 +00002931 std::unique_ptr<std::vector<const char *>> Args(
2932 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002933
2934 // Recover resources if we crash before exiting this method.
2935 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2936 ArgsCleanup(Args.get());
2937
2938 // Since the Clang C library is primarily used by batch tools dealing with
2939 // (often very broken) source code, where spell-checking can have a
2940 // significant negative impact on performance (particularly when
2941 // precompiled headers are involved), we disable it by default.
2942 // Only do this if we haven't found a spell-checking-related argument.
2943 bool FoundSpellCheckingArgument = false;
2944 for (int I = 0; I != num_command_line_args; ++I) {
2945 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2946 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2947 FoundSpellCheckingArgument = true;
2948 break;
2949 }
2950 }
2951 if (!FoundSpellCheckingArgument)
2952 Args->push_back("-fno-spell-checking");
2953
2954 Args->insert(Args->end(), command_line_args,
2955 command_line_args + num_command_line_args);
2956
2957 // The 'source_filename' argument is optional. If the caller does not
2958 // specify it then it is assumed that the source file is specified
2959 // in the actual argument list.
2960 // Put the source file after command_line_args otherwise if '-x' flag is
2961 // present it will be unused.
2962 if (source_filename)
2963 Args->push_back(source_filename);
2964
2965 // Do we need the detailed preprocessing record?
2966 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2967 Args->push_back("-Xclang");
2968 Args->push_back("-detailed-preprocessing-record");
2969 }
2970
2971 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00002972 std::unique_ptr<ASTUnit> ErrUnit;
2973 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Dmitri Gribenko340dd512014-03-12 15:35:53 +00002974 Args->data(), Args->data() + Args->size(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00002975 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
2976 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
2977 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
2978 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
2979 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
2980 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00002981
2982 if (NumErrors != Diags->getClient()->getNumErrors()) {
2983 // Make sure to check that 'Unit' is non-NULL.
2984 if (CXXIdx->getDisplayDiagnostics())
2985 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2986 }
2987
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002988 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
2989 PTUI->result = CXError_ASTReadError;
2990 } else {
Ahmed Charles9a16beb2014-03-07 19:33:25 +00002991 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002992 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
2993 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002994}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002995
2996CXTranslationUnit
2997clang_parseTranslationUnit(CXIndex CIdx,
2998 const char *source_filename,
2999 const char *const *command_line_args,
3000 int num_command_line_args,
3001 struct CXUnsavedFile *unsaved_files,
3002 unsigned num_unsaved_files,
3003 unsigned options) {
3004 CXTranslationUnit TU;
3005 enum CXErrorCode Result = clang_parseTranslationUnit2(
3006 CIdx, source_filename, command_line_args, num_command_line_args,
3007 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00003008 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003009 assert((TU && Result == CXError_Success) ||
3010 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003011 return TU;
3012}
3013
3014enum CXErrorCode clang_parseTranslationUnit2(
3015 CXIndex CIdx,
3016 const char *source_filename,
3017 const char *const *command_line_args,
3018 int num_command_line_args,
3019 struct CXUnsavedFile *unsaved_files,
3020 unsigned num_unsaved_files,
3021 unsigned options,
3022 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003023 LOG_FUNC_SECTION {
3024 *Log << source_filename << ": ";
3025 for (int i = 0; i != num_command_line_args; ++i)
3026 *Log << command_line_args[i] << " ";
3027 }
3028
Alp Toker9d85b182014-07-07 01:23:14 +00003029 if (num_unsaved_files && !unsaved_files)
3030 return CXError_InvalidArguments;
3031
Alp Toker5c532982014-07-07 22:42:03 +00003032 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00003033 ParseTranslationUnitInfo PTUI = {
3034 CIdx,
3035 source_filename,
3036 command_line_args,
3037 num_command_line_args,
3038 llvm::makeArrayRef(unsaved_files, num_unsaved_files),
3039 options,
3040 out_TU,
Alp Toker5c532982014-07-07 22:42:03 +00003041 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00003042 llvm::CrashRecoveryContext CRC;
3043
3044 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
3045 fprintf(stderr, "libclang: crash detected during parsing: {\n");
3046 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3047 fprintf(stderr, " 'command_line_args' : [");
3048 for (int i = 0; i != num_command_line_args; ++i) {
3049 if (i)
3050 fprintf(stderr, ", ");
3051 fprintf(stderr, "'%s'", command_line_args[i]);
3052 }
3053 fprintf(stderr, "],\n");
3054 fprintf(stderr, " 'unsaved_files' : [");
3055 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3056 if (i)
3057 fprintf(stderr, ", ");
3058 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3059 unsaved_files[i].Length);
3060 }
3061 fprintf(stderr, "],\n");
3062 fprintf(stderr, " 'options' : %d,\n", options);
3063 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003064
3065 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003066 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003067 if (CXTranslationUnit *TU = PTUI.out_TU)
3068 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003069 }
Alp Toker5c532982014-07-07 22:42:03 +00003070
3071 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003072}
3073
3074unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
3075 return CXSaveTranslationUnit_None;
3076}
3077
3078namespace {
3079
3080struct SaveTranslationUnitInfo {
3081 CXTranslationUnit TU;
3082 const char *FileName;
3083 unsigned options;
3084 CXSaveError result;
3085};
3086
3087}
3088
3089static void clang_saveTranslationUnit_Impl(void *UserData) {
3090 SaveTranslationUnitInfo *STUI =
3091 static_cast<SaveTranslationUnitInfo*>(UserData);
3092
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003093 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003094 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3095 setThreadBackgroundPriority();
3096
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003097 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00003098 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
3099}
3100
3101int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3102 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003103 LOG_FUNC_SECTION {
3104 *Log << TU << ' ' << FileName;
3105 }
3106
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003107 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003108 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003109 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003110 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003111
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003112 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003113 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3114 if (!CXXUnit->hasSema())
3115 return CXSaveError_InvalidTU;
3116
3117 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
3118
3119 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3120 getenv("LIBCLANG_NOTHREADS")) {
3121 clang_saveTranslationUnit_Impl(&STUI);
3122
3123 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3124 PrintLibclangResourceUsage(TU);
3125
3126 return STUI.result;
3127 }
3128
3129 // We have an AST that has invalid nodes due to compiler errors.
3130 // Use a crash recovery thread for protection.
3131
3132 llvm::CrashRecoveryContext CRC;
3133
3134 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
3135 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3136 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3137 fprintf(stderr, " 'options' : %d,\n", options);
3138 fprintf(stderr, "}\n");
3139
3140 return CXSaveError_Unknown;
3141
3142 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3143 PrintLibclangResourceUsage(TU);
3144 }
3145
3146 return STUI.result;
3147}
3148
3149void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3150 if (CTUnit) {
3151 // If the translation unit has been marked as unsafe to free, just discard
3152 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003153 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3154 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003155 return;
3156
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003157 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003158 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003159 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3160 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003161 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003162 delete CTUnit;
3163 }
3164}
3165
3166unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3167 return CXReparse_None;
3168}
3169
3170struct ReparseTranslationUnitInfo {
3171 CXTranslationUnit TU;
Alp Toker9d85b182014-07-07 01:23:14 +00003172 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00003173 unsigned options;
Alp Toker5c532982014-07-07 22:42:03 +00003174 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003175};
3176
3177static void clang_reparseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00003178 const ReparseTranslationUnitInfo *RTUI =
3179 static_cast<ReparseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00003180 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003181 unsigned options = RTUI->options;
3182 (void) options;
3183
3184 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003185 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003186 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003187 RTUI->result = CXError_InvalidArguments;
3188 return;
3189 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003190
3191 // Reset the associated diagnostics.
3192 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003193 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003194
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003195 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003196 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3197 setThreadBackgroundPriority();
3198
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003199 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003200 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003201
3202 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3203 new std::vector<ASTUnit::RemappedFile>());
3204
Guy Benyei11169dd2012-12-18 14:30:41 +00003205 // Recover resources if we crash before exiting this function.
3206 llvm::CrashRecoveryContextCleanupRegistrar<
3207 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003208
3209 for (auto &UF : RTUI->unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003210 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003211 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003212 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003213 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003214
Dmitri Gribenko2febd212014-02-07 15:00:22 +00003215 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003216 RTUI->result = CXError_Success;
3217 else if (isASTReadError(CXXUnit))
3218 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003219}
3220
3221int clang_reparseTranslationUnit(CXTranslationUnit TU,
3222 unsigned num_unsaved_files,
3223 struct CXUnsavedFile *unsaved_files,
3224 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003225 LOG_FUNC_SECTION {
3226 *Log << TU;
3227 }
3228
Alp Toker9d85b182014-07-07 01:23:14 +00003229 if (num_unsaved_files && !unsaved_files)
3230 return CXError_InvalidArguments;
3231
Alp Toker5c532982014-07-07 22:42:03 +00003232 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00003233 ReparseTranslationUnitInfo RTUI = {
3234 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options,
Alp Toker5c532982014-07-07 22:42:03 +00003235 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00003236
3237 if (getenv("LIBCLANG_NOTHREADS")) {
3238 clang_reparseTranslationUnit_Impl(&RTUI);
Alp Toker5c532982014-07-07 22:42:03 +00003239 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003240 }
3241
3242 llvm::CrashRecoveryContext CRC;
3243
3244 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3245 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003246 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003247 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003248 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3249 PrintLibclangResourceUsage(TU);
3250
Alp Toker5c532982014-07-07 22:42:03 +00003251 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003252}
3253
3254
3255CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003256 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003257 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003258 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003259 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003260
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003261 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003262 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003263}
3264
3265CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003266 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003267 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003268 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003269 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003270
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003271 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003272 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3273}
3274
3275} // end: extern "C"
3276
3277//===----------------------------------------------------------------------===//
3278// CXFile Operations.
3279//===----------------------------------------------------------------------===//
3280
3281extern "C" {
3282CXString clang_getFileName(CXFile SFile) {
3283 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003284 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003285
3286 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003287 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003288}
3289
3290time_t clang_getFileTime(CXFile SFile) {
3291 if (!SFile)
3292 return 0;
3293
3294 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3295 return FEnt->getModificationTime();
3296}
3297
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003298CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003299 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003300 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003301 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003302 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003303
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003304 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003305
3306 FileManager &FMgr = CXXUnit->getFileManager();
3307 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3308}
3309
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003310unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3311 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003312 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003313 LOG_BAD_TU(TU);
3314 return 0;
3315 }
3316
3317 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003318 return 0;
3319
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003320 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003321 FileEntry *FEnt = static_cast<FileEntry *>(file);
3322 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3323 .isFileMultipleIncludeGuarded(FEnt);
3324}
3325
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003326int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3327 if (!file || !outID)
3328 return 1;
3329
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003330 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003331 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3332 outID->data[0] = ID.getDevice();
3333 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003334 outID->data[2] = FEnt->getModificationTime();
3335 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003336}
3337
Argyrios Kyrtzidisac3997e2014-08-16 00:26:19 +00003338int clang_File_isEqual(CXFile file1, CXFile file2) {
3339 if (file1 == file2)
3340 return true;
3341
3342 if (!file1 || !file2)
3343 return false;
3344
3345 FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
3346 FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
3347 return FEnt1->getUniqueID() == FEnt2->getUniqueID();
3348}
3349
Guy Benyei11169dd2012-12-18 14:30:41 +00003350} // end: extern "C"
3351
3352//===----------------------------------------------------------------------===//
3353// CXCursor Operations.
3354//===----------------------------------------------------------------------===//
3355
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003356static const Decl *getDeclFromExpr(const Stmt *E) {
3357 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003358 return getDeclFromExpr(CE->getSubExpr());
3359
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003360 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003361 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003362 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003363 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003364 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003365 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003366 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003367 if (PRE->isExplicitProperty())
3368 return PRE->getExplicitProperty();
3369 // It could be messaging both getter and setter as in:
3370 // ++myobj.myprop;
3371 // in which case prefer to associate the setter since it is less obvious
3372 // from inspecting the source that the setter is going to get called.
3373 if (PRE->isMessagingSetter())
3374 return PRE->getImplicitPropertySetter();
3375 return PRE->getImplicitPropertyGetter();
3376 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003377 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003378 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003379 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003380 if (Expr *Src = OVE->getSourceExpr())
3381 return getDeclFromExpr(Src);
3382
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003383 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003384 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003385 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003386 if (!CE->isElidable())
3387 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003388 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003389 return OME->getMethodDecl();
3390
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003391 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003392 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003393 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003394 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3395 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003396 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003397 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3398 isa<ParmVarDecl>(SizeOfPack->getPack()))
3399 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003400
3401 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003402}
3403
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003404static SourceLocation getLocationFromExpr(const Expr *E) {
3405 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003406 return getLocationFromExpr(CE->getSubExpr());
3407
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003408 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003409 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003410 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003411 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003412 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003413 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003414 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003415 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003416 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003417 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003418 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003419 return PropRef->getLocation();
3420
3421 return E->getLocStart();
3422}
3423
3424extern "C" {
3425
3426unsigned clang_visitChildren(CXCursor parent,
3427 CXCursorVisitor visitor,
3428 CXClientData client_data) {
3429 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3430 /*VisitPreprocessorLast=*/false);
3431 return CursorVis.VisitChildren(parent);
3432}
3433
3434#ifndef __has_feature
3435#define __has_feature(x) 0
3436#endif
3437#if __has_feature(blocks)
3438typedef enum CXChildVisitResult
3439 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3440
3441static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3442 CXClientData client_data) {
3443 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3444 return block(cursor, parent);
3445}
3446#else
3447// If we are compiled with a compiler that doesn't have native blocks support,
3448// define and call the block manually, so the
3449typedef struct _CXChildVisitResult
3450{
3451 void *isa;
3452 int flags;
3453 int reserved;
3454 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3455 CXCursor);
3456} *CXCursorVisitorBlock;
3457
3458static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3459 CXClientData client_data) {
3460 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3461 return block->invoke(block, cursor, parent);
3462}
3463#endif
3464
3465
3466unsigned clang_visitChildrenWithBlock(CXCursor parent,
3467 CXCursorVisitorBlock block) {
3468 return clang_visitChildren(parent, visitWithBlock, block);
3469}
3470
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003471static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003472 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003473 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003474
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003475 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003476 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003477 if (const ObjCPropertyImplDecl *PropImpl =
3478 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003479 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003480 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003481
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003482 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003483 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003484 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003485
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003486 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003487 }
3488
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003489 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003490 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003491
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003492 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003493 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3494 // and returns different names. NamedDecl returns the class name and
3495 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003496 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003497
3498 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003499 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003500
3501 SmallString<1024> S;
3502 llvm::raw_svector_ostream os(S);
3503 ND->printName(os);
3504
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003505 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003506}
3507
3508CXString clang_getCursorSpelling(CXCursor C) {
3509 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003510 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003511
3512 if (clang_isReference(C.kind)) {
3513 switch (C.kind) {
3514 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003515 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003516 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003517 }
3518 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003519 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003520 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003521 }
3522 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003523 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003524 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003525 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003526 }
3527 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003528 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003529 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003530 }
3531 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003532 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003533 assert(Type && "Missing type decl");
3534
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003535 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003536 getAsString());
3537 }
3538 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003539 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003540 assert(Template && "Missing template decl");
3541
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003542 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003543 }
3544
3545 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003546 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003547 assert(NS && "Missing namespace decl");
3548
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003549 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003550 }
3551
3552 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003553 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003554 assert(Field && "Missing member decl");
3555
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003556 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003557 }
3558
3559 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003560 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003561 assert(Label && "Missing label");
3562
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003563 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003564 }
3565
3566 case CXCursor_OverloadedDeclRef: {
3567 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003568 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3569 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003570 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003571 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003572 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003573 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003574 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003575 OverloadedTemplateStorage *Ovl
3576 = Storage.get<OverloadedTemplateStorage*>();
3577 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003578 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003579 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003580 }
3581
3582 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003583 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003584 assert(Var && "Missing variable decl");
3585
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003586 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003587 }
3588
3589 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003590 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003591 }
3592 }
3593
3594 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003595 const Expr *E = getCursorExpr(C);
3596
3597 if (C.kind == CXCursor_ObjCStringLiteral ||
3598 C.kind == CXCursor_StringLiteral) {
3599 const StringLiteral *SLit;
3600 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3601 SLit = OSL->getString();
3602 } else {
3603 SLit = cast<StringLiteral>(E);
3604 }
3605 SmallString<256> Buf;
3606 llvm::raw_svector_ostream OS(Buf);
3607 SLit->outputString(OS);
3608 return cxstring::createDup(OS.str());
3609 }
3610
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003611 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003612 if (D)
3613 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003614 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003615 }
3616
3617 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003618 const Stmt *S = getCursorStmt(C);
3619 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003620 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003621
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003622 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003623 }
3624
3625 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003626 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003627 ->getNameStart());
3628
3629 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003630 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003631 ->getNameStart());
3632
3633 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003634 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003635
3636 if (clang_isDeclaration(C.kind))
3637 return getDeclSpelling(getCursorDecl(C));
3638
3639 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003640 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003641 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003642 }
3643
3644 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003645 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003646 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003647 }
3648
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003649 if (C.kind == CXCursor_PackedAttr) {
3650 return cxstring::createRef("packed");
3651 }
3652
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003653 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003654}
3655
3656CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3657 unsigned pieceIndex,
3658 unsigned options) {
3659 if (clang_Cursor_isNull(C))
3660 return clang_getNullRange();
3661
3662 ASTContext &Ctx = getCursorContext(C);
3663
3664 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003665 const Stmt *S = getCursorStmt(C);
3666 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003667 if (pieceIndex > 0)
3668 return clang_getNullRange();
3669 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3670 }
3671
3672 return clang_getNullRange();
3673 }
3674
3675 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003676 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003677 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3678 if (pieceIndex >= ME->getNumSelectorLocs())
3679 return clang_getNullRange();
3680 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3681 }
3682 }
3683
3684 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3685 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003686 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003687 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3688 if (pieceIndex >= MD->getNumSelectorLocs())
3689 return clang_getNullRange();
3690 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3691 }
3692 }
3693
3694 if (C.kind == CXCursor_ObjCCategoryDecl ||
3695 C.kind == CXCursor_ObjCCategoryImplDecl) {
3696 if (pieceIndex > 0)
3697 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003698 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003699 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3700 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003701 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003702 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3703 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3704 }
3705
3706 if (C.kind == CXCursor_ModuleImportDecl) {
3707 if (pieceIndex > 0)
3708 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003709 if (const ImportDecl *ImportD =
3710 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003711 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3712 if (!Locs.empty())
3713 return cxloc::translateSourceRange(Ctx,
3714 SourceRange(Locs.front(), Locs.back()));
3715 }
3716 return clang_getNullRange();
3717 }
3718
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00003719 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
3720 C.kind == CXCursor_ConversionFunction) {
3721 if (pieceIndex > 0)
3722 return clang_getNullRange();
3723 if (const FunctionDecl *FD =
3724 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
3725 DeclarationNameInfo FunctionName = FD->getNameInfo();
3726 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
3727 }
3728 return clang_getNullRange();
3729 }
3730
Guy Benyei11169dd2012-12-18 14:30:41 +00003731 // FIXME: A CXCursor_InclusionDirective should give the location of the
3732 // filename, but we don't keep track of this.
3733
3734 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3735 // but we don't keep track of this.
3736
3737 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3738 // but we don't keep track of this.
3739
3740 // Default handling, give the location of the cursor.
3741
3742 if (pieceIndex > 0)
3743 return clang_getNullRange();
3744
3745 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3746 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3747 return cxloc::translateSourceRange(Ctx, Loc);
3748}
3749
Eli Bendersky44a206f2014-07-31 18:04:56 +00003750CXString clang_Cursor_getMangling(CXCursor C) {
3751 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
3752 return cxstring::createEmpty();
3753
Eli Bendersky44a206f2014-07-31 18:04:56 +00003754 // Mangling only works for functions and variables.
Eli Bendersky79759592014-08-01 15:01:10 +00003755 const Decl *D = getCursorDecl(C);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003756 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
3757 return cxstring::createEmpty();
3758
Eli Bendersky79759592014-08-01 15:01:10 +00003759 // First apply frontend mangling.
Eli Bendersky44a206f2014-07-31 18:04:56 +00003760 const NamedDecl *ND = cast<NamedDecl>(D);
Eli Bendersky79759592014-08-01 15:01:10 +00003761 ASTContext &Ctx = ND->getASTContext();
3762 std::unique_ptr<MangleContext> MC(Ctx.createMangleContext());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003763
Eli Bendersky79759592014-08-01 15:01:10 +00003764 std::string FrontendBuf;
3765 llvm::raw_string_ostream FrontendBufOS(FrontendBuf);
3766 MC->mangleName(ND, FrontendBufOS);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003767
Eli Bendersky79759592014-08-01 15:01:10 +00003768 // Now apply backend mangling.
3769 std::unique_ptr<llvm::DataLayout> DL(
3770 new llvm::DataLayout(Ctx.getTargetInfo().getTargetDescription()));
3771 llvm::Mangler BackendMangler(DL.get());
3772
3773 std::string FinalBuf;
3774 llvm::raw_string_ostream FinalBufOS(FinalBuf);
3775 BackendMangler.getNameWithPrefix(FinalBufOS,
3776 llvm::Twine(FrontendBufOS.str()));
3777
3778 return cxstring::createDup(FinalBufOS.str());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003779}
3780
Guy Benyei11169dd2012-12-18 14:30:41 +00003781CXString clang_getCursorDisplayName(CXCursor C) {
3782 if (!clang_isDeclaration(C.kind))
3783 return clang_getCursorSpelling(C);
3784
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003785 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003786 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003787 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003788
3789 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003790 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003791 D = FunTmpl->getTemplatedDecl();
3792
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003793 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003794 SmallString<64> Str;
3795 llvm::raw_svector_ostream OS(Str);
3796 OS << *Function;
3797 if (Function->getPrimaryTemplate())
3798 OS << "<>";
3799 OS << "(";
3800 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3801 if (I)
3802 OS << ", ";
3803 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3804 }
3805
3806 if (Function->isVariadic()) {
3807 if (Function->getNumParams())
3808 OS << ", ";
3809 OS << "...";
3810 }
3811 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003812 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003813 }
3814
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003815 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003816 SmallString<64> Str;
3817 llvm::raw_svector_ostream OS(Str);
3818 OS << *ClassTemplate;
3819 OS << "<";
3820 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3821 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3822 if (I)
3823 OS << ", ";
3824
3825 NamedDecl *Param = Params->getParam(I);
3826 if (Param->getIdentifier()) {
3827 OS << Param->getIdentifier()->getName();
3828 continue;
3829 }
3830
3831 // There is no parameter name, which makes this tricky. Try to come up
3832 // with something useful that isn't too long.
3833 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3834 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3835 else if (NonTypeTemplateParmDecl *NTTP
3836 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3837 OS << NTTP->getType().getAsString(Policy);
3838 else
3839 OS << "template<...> class";
3840 }
3841
3842 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003843 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003844 }
3845
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003846 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003847 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3848 // If the type was explicitly written, use that.
3849 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003850 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003851
Benjamin Kramer9170e912013-02-22 15:46:01 +00003852 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003853 llvm::raw_svector_ostream OS(Str);
3854 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003855 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003856 ClassSpec->getTemplateArgs().data(),
3857 ClassSpec->getTemplateArgs().size(),
3858 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003859 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003860 }
3861
3862 return clang_getCursorSpelling(C);
3863}
3864
3865CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3866 switch (Kind) {
3867 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003868 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003869 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003870 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003871 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003872 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003873 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003874 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003875 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003876 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003877 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003878 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003879 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003880 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003881 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003882 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003883 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003884 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003885 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003886 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003887 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003888 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003889 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003890 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003891 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003892 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003893 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003894 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003895 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003896 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003897 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003898 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003899 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003900 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003901 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003902 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003903 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003904 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003905 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003906 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003907 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003908 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003909 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003910 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003911 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003912 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003913 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003914 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003915 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003916 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003917 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003918 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003919 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003920 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003921 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003922 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003923 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003924 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003925 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003926 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003927 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003928 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003929 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003930 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003931 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003932 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003933 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003934 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003935 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003936 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003937 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003938 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003939 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003940 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003941 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003942 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003943 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003944 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003945 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003946 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003947 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003948 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003949 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003950 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003951 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003952 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003953 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003954 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003955 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003956 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003957 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003958 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003959 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003960 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003961 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003962 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003963 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003964 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003965 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003966 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003967 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003968 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003969 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003970 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003971 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003972 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003973 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003974 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003975 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003976 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003977 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003978 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003979 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003980 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003981 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003982 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003983 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003984 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003985 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003986 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003987 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003988 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003989 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003990 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003991 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003992 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003993 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003994 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003995 case CXCursor_ObjCSelfExpr:
3996 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003997 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003998 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003999 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004000 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004001 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004002 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004003 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004004 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004005 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004006 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004007 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004008 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004009 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004010 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004011 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004012 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004013 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004014 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004015 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004016 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004017 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004018 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004019 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004020 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004021 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004022 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004023 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004024 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004025 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004026 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004027 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004028 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004029 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004030 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004031 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004032 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004033 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004034 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004035 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004036 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004037 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004038 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004039 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004040 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004041 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004042 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004043 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004044 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004045 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004046 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004047 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004048 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004049 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004050 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004051 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004052 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004053 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004054 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004055 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004056 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004057 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004058 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004059 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004060 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004061 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004062 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004063 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004064 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004065 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004066 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004067 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004068 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004069 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004070 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004071 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004072 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004073 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004074 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004075 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004076 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004077 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004078 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004079 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004080 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004081 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004082 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004083 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004084 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00004085 case CXCursor_SEHLeaveStmt:
4086 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004087 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004088 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004089 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004090 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00004091 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004092 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00004093 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004094 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00004095 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004096 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00004097 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004098 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00004099 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004100 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004101 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004102 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004103 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004104 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004105 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004106 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004107 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004108 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004109 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004110 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004111 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004112 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004113 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004114 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004115 case CXCursor_PackedAttr:
4116 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00004117 case CXCursor_PureAttr:
4118 return cxstring::createRef("attribute(pure)");
4119 case CXCursor_ConstAttr:
4120 return cxstring::createRef("attribute(const)");
4121 case CXCursor_NoDuplicateAttr:
4122 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00004123 case CXCursor_CUDAConstantAttr:
4124 return cxstring::createRef("attribute(constant)");
4125 case CXCursor_CUDADeviceAttr:
4126 return cxstring::createRef("attribute(device)");
4127 case CXCursor_CUDAGlobalAttr:
4128 return cxstring::createRef("attribute(global)");
4129 case CXCursor_CUDAHostAttr:
4130 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00004131 case CXCursor_CUDASharedAttr:
4132 return cxstring::createRef("attribute(shared)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004133 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004134 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004135 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004136 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00004137 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004138 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004139 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004140 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004141 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004142 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00004143 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004144 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00004145 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004146 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004147 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004148 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004149 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004150 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004151 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004152 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004153 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004154 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004155 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004156 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004157 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004158 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004159 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004160 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004161 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004162 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004163 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004164 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004165 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004166 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004167 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004168 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004169 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004170 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004171 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004172 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004173 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004174 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004175 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004176 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004177 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004178 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004179 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004180 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004181 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004182 return cxstring::createRef("OMPParallelDirective");
4183 case CXCursor_OMPSimdDirective:
4184 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004185 case CXCursor_OMPForDirective:
4186 return cxstring::createRef("OMPForDirective");
Alexander Musmanf82886e2014-09-18 05:12:34 +00004187 case CXCursor_OMPForSimdDirective:
4188 return cxstring::createRef("OMPForSimdDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004189 case CXCursor_OMPSectionsDirective:
4190 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004191 case CXCursor_OMPSectionDirective:
4192 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004193 case CXCursor_OMPSingleDirective:
4194 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004195 case CXCursor_OMPMasterDirective:
4196 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004197 case CXCursor_OMPCriticalDirective:
4198 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004199 case CXCursor_OMPParallelForDirective:
4200 return cxstring::createRef("OMPParallelForDirective");
Alexander Musmane4e893b2014-09-23 09:33:00 +00004201 case CXCursor_OMPParallelForSimdDirective:
4202 return cxstring::createRef("OMPParallelForSimdDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004203 case CXCursor_OMPParallelSectionsDirective:
4204 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004205 case CXCursor_OMPTaskDirective:
4206 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004207 case CXCursor_OMPTaskyieldDirective:
4208 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004209 case CXCursor_OMPBarrierDirective:
4210 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004211 case CXCursor_OMPTaskwaitDirective:
4212 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00004213 case CXCursor_OMPFlushDirective:
4214 return cxstring::createRef("OMPFlushDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004215 case CXCursor_OMPOrderedDirective:
4216 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00004217 case CXCursor_OMPAtomicDirective:
4218 return cxstring::createRef("OMPAtomicDirective");
Alexey Bataev0bd520b2014-09-19 08:19:49 +00004219 case CXCursor_OMPTargetDirective:
4220 return cxstring::createRef("OMPTargetDirective");
Alexey Bataev13314bf2014-10-09 04:18:56 +00004221 case CXCursor_OMPTeamsDirective:
4222 return cxstring::createRef("OMPTeamsDirective");
Francisco Lopes da Silva975a9f62015-01-21 16:24:11 +00004223 case CXCursor_OverloadCandidate:
4224 return cxstring::createRef("OverloadCandidate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004225 }
4226
4227 llvm_unreachable("Unhandled CXCursorKind");
4228}
4229
4230struct GetCursorData {
4231 SourceLocation TokenBeginLoc;
4232 bool PointsAtMacroArgExpansion;
4233 bool VisitedObjCPropertyImplDecl;
4234 SourceLocation VisitedDeclaratorDeclStartLoc;
4235 CXCursor &BestCursor;
4236
4237 GetCursorData(SourceManager &SM,
4238 SourceLocation tokenBegin, CXCursor &outputCursor)
4239 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4240 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4241 VisitedObjCPropertyImplDecl = false;
4242 }
4243};
4244
4245static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4246 CXCursor parent,
4247 CXClientData client_data) {
4248 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4249 CXCursor *BestCursor = &Data->BestCursor;
4250
4251 // If we point inside a macro argument we should provide info of what the
4252 // token is so use the actual cursor, don't replace it with a macro expansion
4253 // cursor.
4254 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4255 return CXChildVisit_Recurse;
4256
4257 if (clang_isDeclaration(cursor.kind)) {
4258 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004259 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004260 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4261 if (MD->isImplicit())
4262 return CXChildVisit_Break;
4263
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004264 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004265 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4266 // Check that when we have multiple @class references in the same line,
4267 // that later ones do not override the previous ones.
4268 // If we have:
4269 // @class Foo, Bar;
4270 // source ranges for both start at '@', so 'Bar' will end up overriding
4271 // 'Foo' even though the cursor location was at 'Foo'.
4272 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4273 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004274 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004275 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4276 if (PrevID != ID &&
4277 !PrevID->isThisDeclarationADefinition() &&
4278 !ID->isThisDeclarationADefinition())
4279 return CXChildVisit_Break;
4280 }
4281
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004282 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004283 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4284 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4285 // Check that when we have multiple declarators in the same line,
4286 // that later ones do not override the previous ones.
4287 // If we have:
4288 // int Foo, Bar;
4289 // source ranges for both start at 'int', so 'Bar' will end up overriding
4290 // 'Foo' even though the cursor location was at 'Foo'.
4291 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4292 return CXChildVisit_Break;
4293 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4294
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004295 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004296 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4297 (void)PropImp;
4298 // Check that when we have multiple @synthesize in the same line,
4299 // that later ones do not override the previous ones.
4300 // If we have:
4301 // @synthesize Foo, Bar;
4302 // source ranges for both start at '@', so 'Bar' will end up overriding
4303 // 'Foo' even though the cursor location was at 'Foo'.
4304 if (Data->VisitedObjCPropertyImplDecl)
4305 return CXChildVisit_Break;
4306 Data->VisitedObjCPropertyImplDecl = true;
4307 }
4308 }
4309
4310 if (clang_isExpression(cursor.kind) &&
4311 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004312 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004313 // Avoid having the cursor of an expression replace the declaration cursor
4314 // when the expression source range overlaps the declaration range.
4315 // This can happen for C++ constructor expressions whose range generally
4316 // include the variable declaration, e.g.:
4317 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4318 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4319 D->getLocation() == Data->TokenBeginLoc)
4320 return CXChildVisit_Break;
4321 }
4322 }
4323
4324 // If our current best cursor is the construction of a temporary object,
4325 // don't replace that cursor with a type reference, because we want
4326 // clang_getCursor() to point at the constructor.
4327 if (clang_isExpression(BestCursor->kind) &&
4328 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4329 cursor.kind == CXCursor_TypeRef) {
4330 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4331 // as having the actual point on the type reference.
4332 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4333 return CXChildVisit_Recurse;
4334 }
4335
4336 *BestCursor = cursor;
4337 return CXChildVisit_Recurse;
4338}
4339
4340CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004341 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004342 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004343 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004344 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004345
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004346 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004347 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4348
4349 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4350 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4351
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004352 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004353 CXFile SearchFile;
4354 unsigned SearchLine, SearchColumn;
4355 CXFile ResultFile;
4356 unsigned ResultLine, ResultColumn;
4357 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4358 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4359 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004360
4361 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4362 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004363 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004364 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004365 SearchFileName = clang_getFileName(SearchFile);
4366 ResultFileName = clang_getFileName(ResultFile);
4367 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4368 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004369 *Log << llvm::format("(%s:%d:%d) = %s",
4370 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4371 clang_getCString(KindSpelling))
4372 << llvm::format("(%s:%d:%d):%s%s",
4373 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4374 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004375 clang_disposeString(SearchFileName);
4376 clang_disposeString(ResultFileName);
4377 clang_disposeString(KindSpelling);
4378 clang_disposeString(USR);
4379
4380 CXCursor Definition = clang_getCursorDefinition(Result);
4381 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4382 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4383 CXString DefinitionKindSpelling
4384 = clang_getCursorKindSpelling(Definition.kind);
4385 CXFile DefinitionFile;
4386 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004387 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004388 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004389 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004390 *Log << llvm::format(" -> %s(%s:%d:%d)",
4391 clang_getCString(DefinitionKindSpelling),
4392 clang_getCString(DefinitionFileName),
4393 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004394 clang_disposeString(DefinitionFileName);
4395 clang_disposeString(DefinitionKindSpelling);
4396 }
4397 }
4398
4399 return Result;
4400}
4401
4402CXCursor clang_getNullCursor(void) {
4403 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4404}
4405
4406unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004407 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4408 // can't set consistently. For example, when visiting a DeclStmt we will set
4409 // it but we don't set it on the result of clang_getCursorDefinition for
4410 // a reference of the same declaration.
4411 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4412 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4413 // to provide that kind of info.
4414 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004415 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004416 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004417 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004418
Guy Benyei11169dd2012-12-18 14:30:41 +00004419 return X == Y;
4420}
4421
4422unsigned clang_hashCursor(CXCursor C) {
4423 unsigned Index = 0;
4424 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4425 Index = 1;
4426
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004427 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004428 std::make_pair(C.kind, C.data[Index]));
4429}
4430
4431unsigned clang_isInvalid(enum CXCursorKind K) {
4432 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4433}
4434
4435unsigned clang_isDeclaration(enum CXCursorKind K) {
4436 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4437 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4438}
4439
4440unsigned clang_isReference(enum CXCursorKind K) {
4441 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4442}
4443
4444unsigned clang_isExpression(enum CXCursorKind K) {
4445 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4446}
4447
4448unsigned clang_isStatement(enum CXCursorKind K) {
4449 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4450}
4451
4452unsigned clang_isAttribute(enum CXCursorKind K) {
4453 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4454}
4455
4456unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4457 return K == CXCursor_TranslationUnit;
4458}
4459
4460unsigned clang_isPreprocessing(enum CXCursorKind K) {
4461 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4462}
4463
4464unsigned clang_isUnexposed(enum CXCursorKind K) {
4465 switch (K) {
4466 case CXCursor_UnexposedDecl:
4467 case CXCursor_UnexposedExpr:
4468 case CXCursor_UnexposedStmt:
4469 case CXCursor_UnexposedAttr:
4470 return true;
4471 default:
4472 return false;
4473 }
4474}
4475
4476CXCursorKind clang_getCursorKind(CXCursor C) {
4477 return C.kind;
4478}
4479
4480CXSourceLocation clang_getCursorLocation(CXCursor C) {
4481 if (clang_isReference(C.kind)) {
4482 switch (C.kind) {
4483 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004484 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004485 = getCursorObjCSuperClassRef(C);
4486 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4487 }
4488
4489 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004490 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004491 = getCursorObjCProtocolRef(C);
4492 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4493 }
4494
4495 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004496 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004497 = getCursorObjCClassRef(C);
4498 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4499 }
4500
4501 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004502 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004503 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4504 }
4505
4506 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004507 std::pair<const TemplateDecl *, SourceLocation> P =
4508 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004509 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4510 }
4511
4512 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004513 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004514 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4515 }
4516
4517 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004518 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004519 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4520 }
4521
4522 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004523 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004524 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4525 }
4526
4527 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004528 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004529 if (!BaseSpec)
4530 return clang_getNullLocation();
4531
4532 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4533 return cxloc::translateSourceLocation(getCursorContext(C),
4534 TSInfo->getTypeLoc().getBeginLoc());
4535
4536 return cxloc::translateSourceLocation(getCursorContext(C),
4537 BaseSpec->getLocStart());
4538 }
4539
4540 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004541 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004542 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4543 }
4544
4545 case CXCursor_OverloadedDeclRef:
4546 return cxloc::translateSourceLocation(getCursorContext(C),
4547 getCursorOverloadedDeclRef(C).second);
4548
4549 default:
4550 // FIXME: Need a way to enumerate all non-reference cases.
4551 llvm_unreachable("Missed a reference kind");
4552 }
4553 }
4554
4555 if (clang_isExpression(C.kind))
4556 return cxloc::translateSourceLocation(getCursorContext(C),
4557 getLocationFromExpr(getCursorExpr(C)));
4558
4559 if (clang_isStatement(C.kind))
4560 return cxloc::translateSourceLocation(getCursorContext(C),
4561 getCursorStmt(C)->getLocStart());
4562
4563 if (C.kind == CXCursor_PreprocessingDirective) {
4564 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4565 return cxloc::translateSourceLocation(getCursorContext(C), L);
4566 }
4567
4568 if (C.kind == CXCursor_MacroExpansion) {
4569 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004570 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004571 return cxloc::translateSourceLocation(getCursorContext(C), L);
4572 }
4573
4574 if (C.kind == CXCursor_MacroDefinition) {
4575 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4576 return cxloc::translateSourceLocation(getCursorContext(C), L);
4577 }
4578
4579 if (C.kind == CXCursor_InclusionDirective) {
4580 SourceLocation L
4581 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4582 return cxloc::translateSourceLocation(getCursorContext(C), L);
4583 }
4584
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004585 if (clang_isAttribute(C.kind)) {
4586 SourceLocation L
4587 = cxcursor::getCursorAttr(C)->getLocation();
4588 return cxloc::translateSourceLocation(getCursorContext(C), L);
4589 }
4590
Guy Benyei11169dd2012-12-18 14:30:41 +00004591 if (!clang_isDeclaration(C.kind))
4592 return clang_getNullLocation();
4593
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004594 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004595 if (!D)
4596 return clang_getNullLocation();
4597
4598 SourceLocation Loc = D->getLocation();
4599 // FIXME: Multiple variables declared in a single declaration
4600 // currently lack the information needed to correctly determine their
4601 // ranges when accounting for the type-specifier. We use context
4602 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4603 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004604 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004605 if (!cxcursor::isFirstInDeclGroup(C))
4606 Loc = VD->getLocation();
4607 }
4608
4609 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004610 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004611 Loc = MD->getSelectorStartLoc();
4612
4613 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4614}
4615
4616} // end extern "C"
4617
4618CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4619 assert(TU);
4620
4621 // Guard against an invalid SourceLocation, or we may assert in one
4622 // of the following calls.
4623 if (SLoc.isInvalid())
4624 return clang_getNullCursor();
4625
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004626 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004627
4628 // Translate the given source location to make it point at the beginning of
4629 // the token under the cursor.
4630 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4631 CXXUnit->getASTContext().getLangOpts());
4632
4633 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4634 if (SLoc.isValid()) {
4635 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4636 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4637 /*VisitPreprocessorLast=*/true,
4638 /*VisitIncludedEntities=*/false,
4639 SourceLocation(SLoc));
4640 CursorVis.visitFileRegion();
4641 }
4642
4643 return Result;
4644}
4645
4646static SourceRange getRawCursorExtent(CXCursor C) {
4647 if (clang_isReference(C.kind)) {
4648 switch (C.kind) {
4649 case CXCursor_ObjCSuperClassRef:
4650 return getCursorObjCSuperClassRef(C).second;
4651
4652 case CXCursor_ObjCProtocolRef:
4653 return getCursorObjCProtocolRef(C).second;
4654
4655 case CXCursor_ObjCClassRef:
4656 return getCursorObjCClassRef(C).second;
4657
4658 case CXCursor_TypeRef:
4659 return getCursorTypeRef(C).second;
4660
4661 case CXCursor_TemplateRef:
4662 return getCursorTemplateRef(C).second;
4663
4664 case CXCursor_NamespaceRef:
4665 return getCursorNamespaceRef(C).second;
4666
4667 case CXCursor_MemberRef:
4668 return getCursorMemberRef(C).second;
4669
4670 case CXCursor_CXXBaseSpecifier:
4671 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4672
4673 case CXCursor_LabelRef:
4674 return getCursorLabelRef(C).second;
4675
4676 case CXCursor_OverloadedDeclRef:
4677 return getCursorOverloadedDeclRef(C).second;
4678
4679 case CXCursor_VariableRef:
4680 return getCursorVariableRef(C).second;
4681
4682 default:
4683 // FIXME: Need a way to enumerate all non-reference cases.
4684 llvm_unreachable("Missed a reference kind");
4685 }
4686 }
4687
4688 if (clang_isExpression(C.kind))
4689 return getCursorExpr(C)->getSourceRange();
4690
4691 if (clang_isStatement(C.kind))
4692 return getCursorStmt(C)->getSourceRange();
4693
4694 if (clang_isAttribute(C.kind))
4695 return getCursorAttr(C)->getRange();
4696
4697 if (C.kind == CXCursor_PreprocessingDirective)
4698 return cxcursor::getCursorPreprocessingDirective(C);
4699
4700 if (C.kind == CXCursor_MacroExpansion) {
4701 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004702 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004703 return TU->mapRangeFromPreamble(Range);
4704 }
4705
4706 if (C.kind == CXCursor_MacroDefinition) {
4707 ASTUnit *TU = getCursorASTUnit(C);
4708 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4709 return TU->mapRangeFromPreamble(Range);
4710 }
4711
4712 if (C.kind == CXCursor_InclusionDirective) {
4713 ASTUnit *TU = getCursorASTUnit(C);
4714 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4715 return TU->mapRangeFromPreamble(Range);
4716 }
4717
4718 if (C.kind == CXCursor_TranslationUnit) {
4719 ASTUnit *TU = getCursorASTUnit(C);
4720 FileID MainID = TU->getSourceManager().getMainFileID();
4721 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4722 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4723 return SourceRange(Start, End);
4724 }
4725
4726 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004727 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004728 if (!D)
4729 return SourceRange();
4730
4731 SourceRange R = D->getSourceRange();
4732 // FIXME: Multiple variables declared in a single declaration
4733 // currently lack the information needed to correctly determine their
4734 // ranges when accounting for the type-specifier. We use context
4735 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4736 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004737 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004738 if (!cxcursor::isFirstInDeclGroup(C))
4739 R.setBegin(VD->getLocation());
4740 }
4741 return R;
4742 }
4743 return SourceRange();
4744}
4745
4746/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4747/// the decl-specifier-seq for declarations.
4748static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4749 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004750 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004751 if (!D)
4752 return SourceRange();
4753
4754 SourceRange R = D->getSourceRange();
4755
4756 // Adjust the start of the location for declarations preceded by
4757 // declaration specifiers.
4758 SourceLocation StartLoc;
4759 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4760 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4761 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004762 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004763 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4764 StartLoc = TI->getTypeLoc().getLocStart();
4765 }
4766
4767 if (StartLoc.isValid() && R.getBegin().isValid() &&
4768 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4769 R.setBegin(StartLoc);
4770
4771 // FIXME: Multiple variables declared in a single declaration
4772 // currently lack the information needed to correctly determine their
4773 // ranges when accounting for the type-specifier. We use context
4774 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4775 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004776 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004777 if (!cxcursor::isFirstInDeclGroup(C))
4778 R.setBegin(VD->getLocation());
4779 }
4780
4781 return R;
4782 }
4783
4784 return getRawCursorExtent(C);
4785}
4786
4787extern "C" {
4788
4789CXSourceRange clang_getCursorExtent(CXCursor C) {
4790 SourceRange R = getRawCursorExtent(C);
4791 if (R.isInvalid())
4792 return clang_getNullRange();
4793
4794 return cxloc::translateSourceRange(getCursorContext(C), R);
4795}
4796
4797CXCursor clang_getCursorReferenced(CXCursor C) {
4798 if (clang_isInvalid(C.kind))
4799 return clang_getNullCursor();
4800
4801 CXTranslationUnit tu = getCursorTU(C);
4802 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004803 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004804 if (!D)
4805 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004806 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004807 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004808 if (const ObjCPropertyImplDecl *PropImpl =
4809 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004810 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4811 return MakeCXCursor(Property, tu);
4812
4813 return C;
4814 }
4815
4816 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004817 const Expr *E = getCursorExpr(C);
4818 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004819 if (D) {
4820 CXCursor declCursor = MakeCXCursor(D, tu);
4821 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4822 declCursor);
4823 return declCursor;
4824 }
4825
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004826 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004827 return MakeCursorOverloadedDeclRef(Ovl, tu);
4828
4829 return clang_getNullCursor();
4830 }
4831
4832 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004833 const Stmt *S = getCursorStmt(C);
4834 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004835 if (LabelDecl *label = Goto->getLabel())
4836 if (LabelStmt *labelS = label->getStmt())
4837 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4838
4839 return clang_getNullCursor();
4840 }
4841
4842 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004843 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004844 return MakeMacroDefinitionCursor(Def, tu);
4845 }
4846
4847 if (!clang_isReference(C.kind))
4848 return clang_getNullCursor();
4849
4850 switch (C.kind) {
4851 case CXCursor_ObjCSuperClassRef:
4852 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4853
4854 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004855 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4856 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004857 return MakeCXCursor(Def, tu);
4858
4859 return MakeCXCursor(Prot, tu);
4860 }
4861
4862 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004863 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4864 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004865 return MakeCXCursor(Def, tu);
4866
4867 return MakeCXCursor(Class, tu);
4868 }
4869
4870 case CXCursor_TypeRef:
4871 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4872
4873 case CXCursor_TemplateRef:
4874 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4875
4876 case CXCursor_NamespaceRef:
4877 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4878
4879 case CXCursor_MemberRef:
4880 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4881
4882 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004883 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004884 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4885 tu ));
4886 }
4887
4888 case CXCursor_LabelRef:
4889 // FIXME: We end up faking the "parent" declaration here because we
4890 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004891 return MakeCXCursor(getCursorLabelRef(C).first,
4892 cxtu::getASTUnit(tu)->getASTContext()
4893 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004894 tu);
4895
4896 case CXCursor_OverloadedDeclRef:
4897 return C;
4898
4899 case CXCursor_VariableRef:
4900 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4901
4902 default:
4903 // We would prefer to enumerate all non-reference cursor kinds here.
4904 llvm_unreachable("Unhandled reference cursor kind");
4905 }
4906}
4907
4908CXCursor clang_getCursorDefinition(CXCursor C) {
4909 if (clang_isInvalid(C.kind))
4910 return clang_getNullCursor();
4911
4912 CXTranslationUnit TU = getCursorTU(C);
4913
4914 bool WasReference = false;
4915 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4916 C = clang_getCursorReferenced(C);
4917 WasReference = true;
4918 }
4919
4920 if (C.kind == CXCursor_MacroExpansion)
4921 return clang_getCursorReferenced(C);
4922
4923 if (!clang_isDeclaration(C.kind))
4924 return clang_getNullCursor();
4925
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004926 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004927 if (!D)
4928 return clang_getNullCursor();
4929
4930 switch (D->getKind()) {
4931 // Declaration kinds that don't really separate the notions of
4932 // declaration and definition.
4933 case Decl::Namespace:
4934 case Decl::Typedef:
4935 case Decl::TypeAlias:
4936 case Decl::TypeAliasTemplate:
4937 case Decl::TemplateTypeParm:
4938 case Decl::EnumConstant:
4939 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004940 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004941 case Decl::IndirectField:
4942 case Decl::ObjCIvar:
4943 case Decl::ObjCAtDefsField:
4944 case Decl::ImplicitParam:
4945 case Decl::ParmVar:
4946 case Decl::NonTypeTemplateParm:
4947 case Decl::TemplateTemplateParm:
4948 case Decl::ObjCCategoryImpl:
4949 case Decl::ObjCImplementation:
4950 case Decl::AccessSpec:
4951 case Decl::LinkageSpec:
4952 case Decl::ObjCPropertyImpl:
4953 case Decl::FileScopeAsm:
4954 case Decl::StaticAssert:
4955 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004956 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004957 case Decl::Label: // FIXME: Is this right??
4958 case Decl::ClassScopeFunctionSpecialization:
4959 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004960 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004961 return C;
4962
4963 // Declaration kinds that don't make any sense here, but are
4964 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004965 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004966 case Decl::TranslationUnit:
Richard Smithf19e1272015-03-07 00:04:49 +00004967 case Decl::ExternCContext:
Guy Benyei11169dd2012-12-18 14:30:41 +00004968 break;
4969
4970 // Declaration kinds for which the definition is not resolvable.
4971 case Decl::UnresolvedUsingTypename:
4972 case Decl::UnresolvedUsingValue:
4973 break;
4974
4975 case Decl::UsingDirective:
4976 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4977 TU);
4978
4979 case Decl::NamespaceAlias:
4980 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4981
4982 case Decl::Enum:
4983 case Decl::Record:
4984 case Decl::CXXRecord:
4985 case Decl::ClassTemplateSpecialization:
4986 case Decl::ClassTemplatePartialSpecialization:
4987 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4988 return MakeCXCursor(Def, TU);
4989 return clang_getNullCursor();
4990
4991 case Decl::Function:
4992 case Decl::CXXMethod:
4993 case Decl::CXXConstructor:
4994 case Decl::CXXDestructor:
4995 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00004996 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004997 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004998 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004999 return clang_getNullCursor();
5000 }
5001
Larisse Voufo39a1e502013-08-06 01:03:05 +00005002 case Decl::Var:
5003 case Decl::VarTemplateSpecialization:
5004 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00005005 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005006 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005007 return MakeCXCursor(Def, TU);
5008 return clang_getNullCursor();
5009 }
5010
5011 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00005012 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005013 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
5014 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
5015 return clang_getNullCursor();
5016 }
5017
5018 case Decl::ClassTemplate: {
5019 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
5020 ->getDefinition())
5021 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
5022 TU);
5023 return clang_getNullCursor();
5024 }
5025
Larisse Voufo39a1e502013-08-06 01:03:05 +00005026 case Decl::VarTemplate: {
5027 if (VarDecl *Def =
5028 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
5029 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
5030 return clang_getNullCursor();
5031 }
5032
Guy Benyei11169dd2012-12-18 14:30:41 +00005033 case Decl::Using:
5034 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
5035 D->getLocation(), TU);
5036
5037 case Decl::UsingShadow:
5038 return clang_getCursorDefinition(
5039 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
5040 TU));
5041
5042 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005043 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005044 if (Method->isThisDeclarationADefinition())
5045 return C;
5046
5047 // Dig out the method definition in the associated
5048 // @implementation, if we have it.
5049 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005050 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005051 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
5052 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
5053 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
5054 Method->isInstanceMethod()))
5055 if (Def->isThisDeclarationADefinition())
5056 return MakeCXCursor(Def, TU);
5057
5058 return clang_getNullCursor();
5059 }
5060
5061 case Decl::ObjCCategory:
5062 if (ObjCCategoryImplDecl *Impl
5063 = cast<ObjCCategoryDecl>(D)->getImplementation())
5064 return MakeCXCursor(Impl, TU);
5065 return clang_getNullCursor();
5066
5067 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005068 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005069 return MakeCXCursor(Def, TU);
5070 return clang_getNullCursor();
5071
5072 case Decl::ObjCInterface: {
5073 // There are two notions of a "definition" for an Objective-C
5074 // class: the interface and its implementation. When we resolved a
5075 // reference to an Objective-C class, produce the @interface as
5076 // the definition; when we were provided with the interface,
5077 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005078 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005079 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005080 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005081 return MakeCXCursor(Def, TU);
5082 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
5083 return MakeCXCursor(Impl, TU);
5084 return clang_getNullCursor();
5085 }
5086
5087 case Decl::ObjCProperty:
5088 // FIXME: We don't really know where to find the
5089 // ObjCPropertyImplDecls that implement this property.
5090 return clang_getNullCursor();
5091
5092 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005093 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005094 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005095 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005096 return MakeCXCursor(Def, TU);
5097
5098 return clang_getNullCursor();
5099
5100 case Decl::Friend:
5101 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
5102 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5103 return clang_getNullCursor();
5104
5105 case Decl::FriendTemplate:
5106 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
5107 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5108 return clang_getNullCursor();
5109 }
5110
5111 return clang_getNullCursor();
5112}
5113
5114unsigned clang_isCursorDefinition(CXCursor C) {
5115 if (!clang_isDeclaration(C.kind))
5116 return 0;
5117
5118 return clang_getCursorDefinition(C) == C;
5119}
5120
5121CXCursor clang_getCanonicalCursor(CXCursor C) {
5122 if (!clang_isDeclaration(C.kind))
5123 return C;
5124
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005125 if (const Decl *D = getCursorDecl(C)) {
5126 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005127 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5128 return MakeCXCursor(CatD, getCursorTU(C));
5129
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005130 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5131 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00005132 return MakeCXCursor(IFD, getCursorTU(C));
5133
5134 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5135 }
5136
5137 return C;
5138}
5139
5140int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5141 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5142}
5143
5144unsigned clang_getNumOverloadedDecls(CXCursor C) {
5145 if (C.kind != CXCursor_OverloadedDeclRef)
5146 return 0;
5147
5148 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005149 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005150 return E->getNumDecls();
5151
5152 if (OverloadedTemplateStorage *S
5153 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5154 return S->size();
5155
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005156 const Decl *D = Storage.get<const Decl *>();
5157 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005158 return Using->shadow_size();
5159
5160 return 0;
5161}
5162
5163CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5164 if (cursor.kind != CXCursor_OverloadedDeclRef)
5165 return clang_getNullCursor();
5166
5167 if (index >= clang_getNumOverloadedDecls(cursor))
5168 return clang_getNullCursor();
5169
5170 CXTranslationUnit TU = getCursorTU(cursor);
5171 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005172 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005173 return MakeCXCursor(E->decls_begin()[index], TU);
5174
5175 if (OverloadedTemplateStorage *S
5176 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5177 return MakeCXCursor(S->begin()[index], TU);
5178
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005179 const Decl *D = Storage.get<const Decl *>();
5180 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005181 // FIXME: This is, unfortunately, linear time.
5182 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5183 std::advance(Pos, index);
5184 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5185 }
5186
5187 return clang_getNullCursor();
5188}
5189
5190void clang_getDefinitionSpellingAndExtent(CXCursor C,
5191 const char **startBuf,
5192 const char **endBuf,
5193 unsigned *startLine,
5194 unsigned *startColumn,
5195 unsigned *endLine,
5196 unsigned *endColumn) {
5197 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005198 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005199 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5200
5201 SourceManager &SM = FD->getASTContext().getSourceManager();
5202 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5203 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5204 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5205 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5206 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5207 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5208}
5209
5210
5211CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5212 unsigned PieceIndex) {
5213 RefNamePieces Pieces;
5214
5215 switch (C.kind) {
5216 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005217 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005218 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5219 E->getQualifierLoc().getSourceRange());
5220 break;
5221
5222 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005223 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005224 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
5225 E->getQualifierLoc().getSourceRange(),
5226 E->getOptionalExplicitTemplateArgs());
5227 break;
5228
5229 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005230 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005231 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005232 const Expr *Callee = OCE->getCallee();
5233 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005234 Callee = ICE->getSubExpr();
5235
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005236 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005237 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5238 DRE->getQualifierLoc().getSourceRange());
5239 }
5240 break;
5241
5242 default:
5243 break;
5244 }
5245
5246 if (Pieces.empty()) {
5247 if (PieceIndex == 0)
5248 return clang_getCursorExtent(C);
5249 } else if (PieceIndex < Pieces.size()) {
5250 SourceRange R = Pieces[PieceIndex];
5251 if (R.isValid())
5252 return cxloc::translateSourceRange(getCursorContext(C), R);
5253 }
5254
5255 return clang_getNullRange();
5256}
5257
5258void clang_enableStackTraces(void) {
5259 llvm::sys::PrintStackTraceOnErrorSignal();
5260}
5261
5262void clang_executeOnThread(void (*fn)(void*), void *user_data,
5263 unsigned stack_size) {
5264 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5265}
5266
5267} // end: extern "C"
5268
5269//===----------------------------------------------------------------------===//
5270// Token-based Operations.
5271//===----------------------------------------------------------------------===//
5272
5273/* CXToken layout:
5274 * int_data[0]: a CXTokenKind
5275 * int_data[1]: starting token location
5276 * int_data[2]: token length
5277 * int_data[3]: reserved
5278 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5279 * otherwise unused.
5280 */
5281extern "C" {
5282
5283CXTokenKind clang_getTokenKind(CXToken CXTok) {
5284 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5285}
5286
5287CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5288 switch (clang_getTokenKind(CXTok)) {
5289 case CXToken_Identifier:
5290 case CXToken_Keyword:
5291 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005292 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005293 ->getNameStart());
5294
5295 case CXToken_Literal: {
5296 // We have stashed the starting pointer in the ptr_data field. Use it.
5297 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005298 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005299 }
5300
5301 case CXToken_Punctuation:
5302 case CXToken_Comment:
5303 break;
5304 }
5305
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005306 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005307 LOG_BAD_TU(TU);
5308 return cxstring::createEmpty();
5309 }
5310
Guy Benyei11169dd2012-12-18 14:30:41 +00005311 // We have to find the starting buffer pointer the hard way, by
5312 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005313 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005314 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005315 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005316
5317 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5318 std::pair<FileID, unsigned> LocInfo
5319 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5320 bool Invalid = false;
5321 StringRef Buffer
5322 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5323 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005324 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005325
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005326 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005327}
5328
5329CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005330 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005331 LOG_BAD_TU(TU);
5332 return clang_getNullLocation();
5333 }
5334
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005335 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005336 if (!CXXUnit)
5337 return clang_getNullLocation();
5338
5339 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5340 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5341}
5342
5343CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005344 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005345 LOG_BAD_TU(TU);
5346 return clang_getNullRange();
5347 }
5348
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005349 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005350 if (!CXXUnit)
5351 return clang_getNullRange();
5352
5353 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5354 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5355}
5356
5357static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5358 SmallVectorImpl<CXToken> &CXTokens) {
5359 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5360 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005361 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005362 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005363 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005364
5365 // Cannot tokenize across files.
5366 if (BeginLocInfo.first != EndLocInfo.first)
5367 return;
5368
5369 // Create a lexer
5370 bool Invalid = false;
5371 StringRef Buffer
5372 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5373 if (Invalid)
5374 return;
5375
5376 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5377 CXXUnit->getASTContext().getLangOpts(),
5378 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5379 Lex.SetCommentRetentionState(true);
5380
5381 // Lex tokens until we hit the end of the range.
5382 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5383 Token Tok;
5384 bool previousWasAt = false;
5385 do {
5386 // Lex the next token
5387 Lex.LexFromRawLexer(Tok);
5388 if (Tok.is(tok::eof))
5389 break;
5390
5391 // Initialize the CXToken.
5392 CXToken CXTok;
5393
5394 // - Common fields
5395 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5396 CXTok.int_data[2] = Tok.getLength();
5397 CXTok.int_data[3] = 0;
5398
5399 // - Kind-specific fields
5400 if (Tok.isLiteral()) {
5401 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005402 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005403 } else if (Tok.is(tok::raw_identifier)) {
5404 // Lookup the identifier to determine whether we have a keyword.
5405 IdentifierInfo *II
5406 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5407
5408 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5409 CXTok.int_data[0] = CXToken_Keyword;
5410 }
5411 else {
5412 CXTok.int_data[0] = Tok.is(tok::identifier)
5413 ? CXToken_Identifier
5414 : CXToken_Keyword;
5415 }
5416 CXTok.ptr_data = II;
5417 } else if (Tok.is(tok::comment)) {
5418 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005419 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005420 } else {
5421 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005422 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005423 }
5424 CXTokens.push_back(CXTok);
5425 previousWasAt = Tok.is(tok::at);
5426 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5427}
5428
5429void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5430 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005431 LOG_FUNC_SECTION {
5432 *Log << TU << ' ' << Range;
5433 }
5434
Guy Benyei11169dd2012-12-18 14:30:41 +00005435 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005436 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005437 if (NumTokens)
5438 *NumTokens = 0;
5439
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005440 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005441 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005442 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005443 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005444
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005445 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005446 if (!CXXUnit || !Tokens || !NumTokens)
5447 return;
5448
5449 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5450
5451 SourceRange R = cxloc::translateCXSourceRange(Range);
5452 if (R.isInvalid())
5453 return;
5454
5455 SmallVector<CXToken, 32> CXTokens;
5456 getTokens(CXXUnit, R, CXTokens);
5457
5458 if (CXTokens.empty())
5459 return;
5460
5461 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5462 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5463 *NumTokens = CXTokens.size();
5464}
5465
5466void clang_disposeTokens(CXTranslationUnit TU,
5467 CXToken *Tokens, unsigned NumTokens) {
5468 free(Tokens);
5469}
5470
5471} // end: extern "C"
5472
5473//===----------------------------------------------------------------------===//
5474// Token annotation APIs.
5475//===----------------------------------------------------------------------===//
5476
Guy Benyei11169dd2012-12-18 14:30:41 +00005477static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5478 CXCursor parent,
5479 CXClientData client_data);
5480static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5481 CXClientData client_data);
5482
5483namespace {
5484class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005485 CXToken *Tokens;
5486 CXCursor *Cursors;
5487 unsigned NumTokens;
5488 unsigned TokIdx;
5489 unsigned PreprocessingTokIdx;
5490 CursorVisitor AnnotateVis;
5491 SourceManager &SrcMgr;
5492 bool HasContextSensitiveKeywords;
5493
5494 struct PostChildrenInfo {
5495 CXCursor Cursor;
5496 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005497 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005498 unsigned BeforeChildrenTokenIdx;
5499 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005500 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005501
5502 CXToken &getTok(unsigned Idx) {
5503 assert(Idx < NumTokens);
5504 return Tokens[Idx];
5505 }
5506 const CXToken &getTok(unsigned Idx) const {
5507 assert(Idx < NumTokens);
5508 return Tokens[Idx];
5509 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005510 bool MoreTokens() const { return TokIdx < NumTokens; }
5511 unsigned NextToken() const { return TokIdx; }
5512 void AdvanceToken() { ++TokIdx; }
5513 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005514 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005515 }
5516 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005517 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005518 }
5519 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005520 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005521 }
5522
5523 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005524 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005525 SourceRange);
5526
5527public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005528 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005529 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005530 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005531 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005532 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005533 AnnotateTokensVisitor, this,
5534 /*VisitPreprocessorLast=*/true,
5535 /*VisitIncludedEntities=*/false,
5536 RegionOfInterest,
5537 /*VisitDeclsOnly=*/false,
5538 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005539 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005540 HasContextSensitiveKeywords(false) { }
5541
5542 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5543 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5544 bool postVisitChildren(CXCursor cursor);
5545 void AnnotateTokens();
5546
5547 /// \brief Determine whether the annotator saw any cursors that have
5548 /// context-sensitive keywords.
5549 bool hasContextSensitiveKeywords() const {
5550 return HasContextSensitiveKeywords;
5551 }
5552
5553 ~AnnotateTokensWorker() {
5554 assert(PostChildrenInfos.empty());
5555 }
5556};
5557}
5558
5559void AnnotateTokensWorker::AnnotateTokens() {
5560 // Walk the AST within the region of interest, annotating tokens
5561 // along the way.
5562 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005563}
Guy Benyei11169dd2012-12-18 14:30:41 +00005564
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005565static inline void updateCursorAnnotation(CXCursor &Cursor,
5566 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005567 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005568 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005569 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005570}
5571
5572/// \brief It annotates and advances tokens with a cursor until the comparison
5573//// between the cursor location and the source range is the same as
5574/// \arg compResult.
5575///
5576/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5577/// Pass RangeOverlap to annotate tokens inside a range.
5578void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5579 RangeComparisonResult compResult,
5580 SourceRange range) {
5581 while (MoreTokens()) {
5582 const unsigned I = NextToken();
5583 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005584 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5585 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005586
5587 SourceLocation TokLoc = GetTokenLoc(I);
5588 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005589 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005590 AdvanceToken();
5591 continue;
5592 }
5593 break;
5594 }
5595}
5596
5597/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005598/// \returns true if it advanced beyond all macro tokens, false otherwise.
5599bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005600 CXCursor updateC,
5601 RangeComparisonResult compResult,
5602 SourceRange range) {
5603 assert(MoreTokens());
5604 assert(isFunctionMacroToken(NextToken()) &&
5605 "Should be called only for macro arg tokens");
5606
5607 // This works differently than annotateAndAdvanceTokens; because expanded
5608 // macro arguments can have arbitrary translation-unit source order, we do not
5609 // advance the token index one by one until a token fails the range test.
5610 // We only advance once past all of the macro arg tokens if all of them
5611 // pass the range test. If one of them fails we keep the token index pointing
5612 // at the start of the macro arg tokens so that the failing token will be
5613 // annotated by a subsequent annotation try.
5614
5615 bool atLeastOneCompFail = false;
5616
5617 unsigned I = NextToken();
5618 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5619 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5620 if (TokLoc.isFileID())
5621 continue; // not macro arg token, it's parens or comma.
5622 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5623 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5624 Cursors[I] = updateC;
5625 } else
5626 atLeastOneCompFail = true;
5627 }
5628
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005629 if (atLeastOneCompFail)
5630 return false;
5631
5632 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5633 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005634}
5635
5636enum CXChildVisitResult
5637AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005638 SourceRange cursorRange = getRawCursorExtent(cursor);
5639 if (cursorRange.isInvalid())
5640 return CXChildVisit_Recurse;
5641
5642 if (!HasContextSensitiveKeywords) {
5643 // Objective-C properties can have context-sensitive keywords.
5644 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005645 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005646 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5647 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5648 }
5649 // Objective-C methods can have context-sensitive keywords.
5650 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5651 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005652 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005653 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5654 if (Method->getObjCDeclQualifier())
5655 HasContextSensitiveKeywords = true;
5656 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005657 for (const auto *P : Method->params()) {
5658 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005659 HasContextSensitiveKeywords = true;
5660 break;
5661 }
5662 }
5663 }
5664 }
5665 }
5666 // C++ methods can have context-sensitive keywords.
5667 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005668 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005669 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5670 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5671 HasContextSensitiveKeywords = true;
5672 }
5673 }
5674 // C++ classes can have context-sensitive keywords.
5675 else if (cursor.kind == CXCursor_StructDecl ||
5676 cursor.kind == CXCursor_ClassDecl ||
5677 cursor.kind == CXCursor_ClassTemplate ||
5678 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005679 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005680 if (D->hasAttr<FinalAttr>())
5681 HasContextSensitiveKeywords = true;
5682 }
5683 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005684
5685 // Don't override a property annotation with its getter/setter method.
5686 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5687 parent.kind == CXCursor_ObjCPropertyDecl)
5688 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005689
5690 if (clang_isPreprocessing(cursor.kind)) {
5691 // Items in the preprocessing record are kept separate from items in
5692 // declarations, so we keep a separate token index.
5693 unsigned SavedTokIdx = TokIdx;
5694 TokIdx = PreprocessingTokIdx;
5695
5696 // Skip tokens up until we catch up to the beginning of the preprocessing
5697 // entry.
5698 while (MoreTokens()) {
5699 const unsigned I = NextToken();
5700 SourceLocation TokLoc = GetTokenLoc(I);
5701 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5702 case RangeBefore:
5703 AdvanceToken();
5704 continue;
5705 case RangeAfter:
5706 case RangeOverlap:
5707 break;
5708 }
5709 break;
5710 }
5711
5712 // Look at all of the tokens within this range.
5713 while (MoreTokens()) {
5714 const unsigned I = NextToken();
5715 SourceLocation TokLoc = GetTokenLoc(I);
5716 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5717 case RangeBefore:
5718 llvm_unreachable("Infeasible");
5719 case RangeAfter:
5720 break;
5721 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005722 // For macro expansions, just note where the beginning of the macro
5723 // expansion occurs.
5724 if (cursor.kind == CXCursor_MacroExpansion) {
5725 if (TokLoc == cursorRange.getBegin())
5726 Cursors[I] = cursor;
5727 AdvanceToken();
5728 break;
5729 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005730 // We may have already annotated macro names inside macro definitions.
5731 if (Cursors[I].kind != CXCursor_MacroExpansion)
5732 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005733 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005734 continue;
5735 }
5736 break;
5737 }
5738
5739 // Save the preprocessing token index; restore the non-preprocessing
5740 // token index.
5741 PreprocessingTokIdx = TokIdx;
5742 TokIdx = SavedTokIdx;
5743 return CXChildVisit_Recurse;
5744 }
5745
5746 if (cursorRange.isInvalid())
5747 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005748
5749 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005750 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005751 const enum CXCursorKind K = clang_getCursorKind(parent);
5752 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005753 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5754 // Attributes are annotated out-of-order, skip tokens until we reach it.
5755 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005756 ? clang_getNullCursor() : parent;
5757
5758 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5759
5760 // Avoid having the cursor of an expression "overwrite" the annotation of the
5761 // variable declaration that it belongs to.
5762 // This can happen for C++ constructor expressions whose range generally
5763 // include the variable declaration, e.g.:
5764 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005765 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005766 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005767 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005768 const unsigned I = NextToken();
5769 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5770 E->getLocStart() == D->getLocation() &&
5771 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005772 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005773 AdvanceToken();
5774 }
5775 }
5776 }
5777
5778 // Before recursing into the children keep some state that we are going
5779 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5780 // extra work after the child nodes are visited.
5781 // Note that we don't call VisitChildren here to avoid traversing statements
5782 // code-recursively which can blow the stack.
5783
5784 PostChildrenInfo Info;
5785 Info.Cursor = cursor;
5786 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005787 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005788 Info.BeforeChildrenTokenIdx = NextToken();
5789 PostChildrenInfos.push_back(Info);
5790
5791 return CXChildVisit_Recurse;
5792}
5793
5794bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5795 if (PostChildrenInfos.empty())
5796 return false;
5797 const PostChildrenInfo &Info = PostChildrenInfos.back();
5798 if (!clang_equalCursors(Info.Cursor, cursor))
5799 return false;
5800
5801 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5802 const unsigned AfterChildren = NextToken();
5803 SourceRange cursorRange = Info.CursorRange;
5804
5805 // Scan the tokens that are at the end of the cursor, but are not captured
5806 // but the child cursors.
5807 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5808
5809 // Scan the tokens that are at the beginning of the cursor, but are not
5810 // capture by the child cursors.
5811 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5812 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5813 break;
5814
5815 Cursors[I] = cursor;
5816 }
5817
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005818 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5819 // encountered the attribute cursor.
5820 if (clang_isAttribute(cursor.kind))
5821 TokIdx = Info.BeforeReachingCursorIdx;
5822
Guy Benyei11169dd2012-12-18 14:30:41 +00005823 PostChildrenInfos.pop_back();
5824 return false;
5825}
5826
5827static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5828 CXCursor parent,
5829 CXClientData client_data) {
5830 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5831}
5832
5833static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5834 CXClientData client_data) {
5835 return static_cast<AnnotateTokensWorker*>(client_data)->
5836 postVisitChildren(cursor);
5837}
5838
5839namespace {
5840
5841/// \brief Uses the macro expansions in the preprocessing record to find
5842/// and mark tokens that are macro arguments. This info is used by the
5843/// AnnotateTokensWorker.
5844class MarkMacroArgTokensVisitor {
5845 SourceManager &SM;
5846 CXToken *Tokens;
5847 unsigned NumTokens;
5848 unsigned CurIdx;
5849
5850public:
5851 MarkMacroArgTokensVisitor(SourceManager &SM,
5852 CXToken *tokens, unsigned numTokens)
5853 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5854
5855 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5856 if (cursor.kind != CXCursor_MacroExpansion)
5857 return CXChildVisit_Continue;
5858
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005859 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005860 if (macroRange.getBegin() == macroRange.getEnd())
5861 return CXChildVisit_Continue; // it's not a function macro.
5862
5863 for (; CurIdx < NumTokens; ++CurIdx) {
5864 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5865 macroRange.getBegin()))
5866 break;
5867 }
5868
5869 if (CurIdx == NumTokens)
5870 return CXChildVisit_Break;
5871
5872 for (; CurIdx < NumTokens; ++CurIdx) {
5873 SourceLocation tokLoc = getTokenLoc(CurIdx);
5874 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5875 break;
5876
5877 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5878 }
5879
5880 if (CurIdx == NumTokens)
5881 return CXChildVisit_Break;
5882
5883 return CXChildVisit_Continue;
5884 }
5885
5886private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005887 CXToken &getTok(unsigned Idx) {
5888 assert(Idx < NumTokens);
5889 return Tokens[Idx];
5890 }
5891 const CXToken &getTok(unsigned Idx) const {
5892 assert(Idx < NumTokens);
5893 return Tokens[Idx];
5894 }
5895
Guy Benyei11169dd2012-12-18 14:30:41 +00005896 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005897 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005898 }
5899
5900 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5901 // The third field is reserved and currently not used. Use it here
5902 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005903 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005904 }
5905};
5906
5907} // end anonymous namespace
5908
5909static CXChildVisitResult
5910MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5911 CXClientData client_data) {
5912 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5913 parent);
5914}
5915
5916namespace {
5917 struct clang_annotateTokens_Data {
5918 CXTranslationUnit TU;
5919 ASTUnit *CXXUnit;
5920 CXToken *Tokens;
5921 unsigned NumTokens;
5922 CXCursor *Cursors;
5923 };
5924}
5925
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005926/// \brief Used by \c annotatePreprocessorTokens.
5927/// \returns true if lexing was finished, false otherwise.
5928static bool lexNext(Lexer &Lex, Token &Tok,
5929 unsigned &NextIdx, unsigned NumTokens) {
5930 if (NextIdx >= NumTokens)
5931 return true;
5932
5933 ++NextIdx;
5934 Lex.LexFromRawLexer(Tok);
5935 if (Tok.is(tok::eof))
5936 return true;
5937
5938 return false;
5939}
5940
Guy Benyei11169dd2012-12-18 14:30:41 +00005941static void annotatePreprocessorTokens(CXTranslationUnit TU,
5942 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005943 CXCursor *Cursors,
5944 CXToken *Tokens,
5945 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005946 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005947
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005948 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005949 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5950 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005951 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005952 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005953 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005954
5955 if (BeginLocInfo.first != EndLocInfo.first)
5956 return;
5957
5958 StringRef Buffer;
5959 bool Invalid = false;
5960 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5961 if (Buffer.empty() || Invalid)
5962 return;
5963
5964 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5965 CXXUnit->getASTContext().getLangOpts(),
5966 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5967 Buffer.end());
5968 Lex.SetCommentRetentionState(true);
5969
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005970 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005971 // Lex tokens in raw mode until we hit the end of the range, to avoid
5972 // entering #includes or expanding macros.
5973 while (true) {
5974 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005975 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5976 break;
5977 unsigned TokIdx = NextIdx-1;
5978 assert(Tok.getLocation() ==
5979 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005980
5981 reprocess:
5982 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005983 // We have found a preprocessing directive. Annotate the tokens
5984 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005985 //
5986 // FIXME: Some simple tests here could identify macro definitions and
5987 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005988
5989 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005990 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5991 break;
5992
Craig Topper69186e72014-06-08 08:38:04 +00005993 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00005994 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005995 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5996 break;
5997
5998 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00005999 IdentifierInfo &II =
6000 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006001 SourceLocation MappedTokLoc =
6002 CXXUnit->mapLocationToPreamble(Tok.getLocation());
6003 MI = getMacroInfo(II, MappedTokLoc, TU);
6004 }
6005 }
6006
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006007 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00006008 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006009 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
6010 finished = true;
6011 break;
6012 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006013 // If we are in a macro definition, check if the token was ever a
6014 // macro name and annotate it if that's the case.
6015 if (MI) {
6016 SourceLocation SaveLoc = Tok.getLocation();
6017 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
6018 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
6019 Tok.setLocation(SaveLoc);
6020 if (MacroDef)
6021 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
6022 Tok.getLocation(), TU);
6023 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006024 } while (!Tok.isAtStartOfLine());
6025
6026 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
6027 assert(TokIdx <= LastIdx);
6028 SourceLocation EndLoc =
6029 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
6030 CXCursor Cursor =
6031 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
6032
6033 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006034 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006035
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006036 if (finished)
6037 break;
6038 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00006039 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006040 }
6041}
6042
6043// This gets run a separate thread to avoid stack blowout.
6044static void clang_annotateTokensImpl(void *UserData) {
6045 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
6046 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
6047 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
6048 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
6049 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
6050
Dmitri Gribenko183436e2013-01-26 21:49:50 +00006051 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006052 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
6053 setThreadBackgroundPriority();
6054
6055 // Determine the region of interest, which contains all of the tokens.
6056 SourceRange RegionOfInterest;
6057 RegionOfInterest.setBegin(
6058 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
6059 RegionOfInterest.setEnd(
6060 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
6061 Tokens[NumTokens-1])));
6062
Guy Benyei11169dd2012-12-18 14:30:41 +00006063 // Relex the tokens within the source range to look for preprocessing
6064 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006065 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006066
6067 // If begin location points inside a macro argument, set it to the expansion
6068 // location so we can have the full context when annotating semantically.
6069 {
6070 SourceManager &SM = CXXUnit->getSourceManager();
6071 SourceLocation Loc =
6072 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
6073 if (Loc.isMacroID())
6074 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
6075 }
6076
Guy Benyei11169dd2012-12-18 14:30:41 +00006077 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
6078 // Search and mark tokens that are macro argument expansions.
6079 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
6080 Tokens, NumTokens);
6081 CursorVisitor MacroArgMarker(TU,
6082 MarkMacroArgTokensVisitorDelegate, &Visitor,
6083 /*VisitPreprocessorLast=*/true,
6084 /*VisitIncludedEntities=*/false,
6085 RegionOfInterest);
6086 MacroArgMarker.visitPreprocessedEntitiesInRegion();
6087 }
6088
6089 // Annotate all of the source locations in the region of interest that map to
6090 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006091 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00006092
6093 // FIXME: We use a ridiculous stack size here because the data-recursion
6094 // algorithm uses a large stack frame than the non-data recursive version,
6095 // and AnnotationTokensWorker currently transforms the data-recursion
6096 // algorithm back into a traditional recursion by explicitly calling
6097 // VisitChildren(). We will need to remove this explicit recursive call.
6098 W.AnnotateTokens();
6099
6100 // If we ran into any entities that involve context-sensitive keywords,
6101 // take another pass through the tokens to mark them as such.
6102 if (W.hasContextSensitiveKeywords()) {
6103 for (unsigned I = 0; I != NumTokens; ++I) {
6104 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
6105 continue;
6106
6107 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
6108 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006109 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006110 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
6111 if (Property->getPropertyAttributesAsWritten() != 0 &&
6112 llvm::StringSwitch<bool>(II->getName())
6113 .Case("readonly", true)
6114 .Case("assign", true)
6115 .Case("unsafe_unretained", true)
6116 .Case("readwrite", true)
6117 .Case("retain", true)
6118 .Case("copy", true)
6119 .Case("nonatomic", true)
6120 .Case("atomic", true)
6121 .Case("getter", true)
6122 .Case("setter", true)
6123 .Case("strong", true)
6124 .Case("weak", true)
6125 .Default(false))
6126 Tokens[I].int_data[0] = CXToken_Keyword;
6127 }
6128 continue;
6129 }
6130
6131 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6132 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6133 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6134 if (llvm::StringSwitch<bool>(II->getName())
6135 .Case("in", true)
6136 .Case("out", true)
6137 .Case("inout", true)
6138 .Case("oneway", true)
6139 .Case("bycopy", true)
6140 .Case("byref", true)
6141 .Default(false))
6142 Tokens[I].int_data[0] = CXToken_Keyword;
6143 continue;
6144 }
6145
6146 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6147 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6148 Tokens[I].int_data[0] = CXToken_Keyword;
6149 continue;
6150 }
6151 }
6152 }
6153}
6154
6155extern "C" {
6156
6157void clang_annotateTokens(CXTranslationUnit TU,
6158 CXToken *Tokens, unsigned NumTokens,
6159 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006160 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006161 LOG_BAD_TU(TU);
6162 return;
6163 }
6164 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006165 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006166 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006167 }
6168
6169 LOG_FUNC_SECTION {
6170 *Log << TU << ' ';
6171 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6172 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6173 *Log << clang_getRange(bloc, eloc);
6174 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006175
6176 // Any token we don't specifically annotate will have a NULL cursor.
6177 CXCursor C = clang_getNullCursor();
6178 for (unsigned I = 0; I != NumTokens; ++I)
6179 Cursors[I] = C;
6180
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006181 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006182 if (!CXXUnit)
6183 return;
6184
6185 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
6186
6187 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
6188 llvm::CrashRecoveryContext CRC;
6189 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
6190 GetSafetyThreadStackSize() * 2)) {
6191 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6192 }
6193}
6194
6195} // end: extern "C"
6196
6197//===----------------------------------------------------------------------===//
6198// Operations for querying linkage of a cursor.
6199//===----------------------------------------------------------------------===//
6200
6201extern "C" {
6202CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6203 if (!clang_isDeclaration(cursor.kind))
6204 return CXLinkage_Invalid;
6205
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006206 const Decl *D = cxcursor::getCursorDecl(cursor);
6207 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006208 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006209 case NoLinkage:
6210 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006211 case InternalLinkage: return CXLinkage_Internal;
6212 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6213 case ExternalLinkage: return CXLinkage_External;
6214 };
6215
6216 return CXLinkage_Invalid;
6217}
6218} // end: extern "C"
6219
6220//===----------------------------------------------------------------------===//
6221// Operations for querying language of a cursor.
6222//===----------------------------------------------------------------------===//
6223
6224static CXLanguageKind getDeclLanguage(const Decl *D) {
6225 if (!D)
6226 return CXLanguage_C;
6227
6228 switch (D->getKind()) {
6229 default:
6230 break;
6231 case Decl::ImplicitParam:
6232 case Decl::ObjCAtDefsField:
6233 case Decl::ObjCCategory:
6234 case Decl::ObjCCategoryImpl:
6235 case Decl::ObjCCompatibleAlias:
6236 case Decl::ObjCImplementation:
6237 case Decl::ObjCInterface:
6238 case Decl::ObjCIvar:
6239 case Decl::ObjCMethod:
6240 case Decl::ObjCProperty:
6241 case Decl::ObjCPropertyImpl:
6242 case Decl::ObjCProtocol:
6243 return CXLanguage_ObjC;
6244 case Decl::CXXConstructor:
6245 case Decl::CXXConversion:
6246 case Decl::CXXDestructor:
6247 case Decl::CXXMethod:
6248 case Decl::CXXRecord:
6249 case Decl::ClassTemplate:
6250 case Decl::ClassTemplatePartialSpecialization:
6251 case Decl::ClassTemplateSpecialization:
6252 case Decl::Friend:
6253 case Decl::FriendTemplate:
6254 case Decl::FunctionTemplate:
6255 case Decl::LinkageSpec:
6256 case Decl::Namespace:
6257 case Decl::NamespaceAlias:
6258 case Decl::NonTypeTemplateParm:
6259 case Decl::StaticAssert:
6260 case Decl::TemplateTemplateParm:
6261 case Decl::TemplateTypeParm:
6262 case Decl::UnresolvedUsingTypename:
6263 case Decl::UnresolvedUsingValue:
6264 case Decl::Using:
6265 case Decl::UsingDirective:
6266 case Decl::UsingShadow:
6267 return CXLanguage_CPlusPlus;
6268 }
6269
6270 return CXLanguage_C;
6271}
6272
6273extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006274
6275static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6276 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
6277 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00006278
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006279 switch (D->getAvailability()) {
6280 case AR_Available:
6281 case AR_NotYetIntroduced:
6282 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006283 return getCursorAvailabilityForDecl(
6284 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006285 return CXAvailability_Available;
6286
6287 case AR_Deprecated:
6288 return CXAvailability_Deprecated;
6289
6290 case AR_Unavailable:
6291 return CXAvailability_NotAvailable;
6292 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006293
6294 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006295}
6296
Guy Benyei11169dd2012-12-18 14:30:41 +00006297enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6298 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006299 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6300 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006301
6302 return CXAvailability_Available;
6303}
6304
6305static CXVersion convertVersion(VersionTuple In) {
6306 CXVersion Out = { -1, -1, -1 };
6307 if (In.empty())
6308 return Out;
6309
6310 Out.Major = In.getMajor();
6311
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006312 Optional<unsigned> Minor = In.getMinor();
6313 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006314 Out.Minor = *Minor;
6315 else
6316 return Out;
6317
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006318 Optional<unsigned> Subminor = In.getSubminor();
6319 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006320 Out.Subminor = *Subminor;
6321
6322 return Out;
6323}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006324
6325static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6326 int *always_deprecated,
6327 CXString *deprecated_message,
6328 int *always_unavailable,
6329 CXString *unavailable_message,
6330 CXPlatformAvailability *availability,
6331 int availability_size) {
6332 bool HadAvailAttr = false;
6333 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006334 for (auto A : D->attrs()) {
6335 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006336 HadAvailAttr = true;
6337 if (always_deprecated)
6338 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006339 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006340 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006341 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006342 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006343 continue;
6344 }
6345
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006346 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006347 HadAvailAttr = true;
6348 if (always_unavailable)
6349 *always_unavailable = 1;
6350 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006351 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006352 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6353 }
6354 continue;
6355 }
6356
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006357 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006358 HadAvailAttr = true;
6359 if (N < availability_size) {
6360 availability[N].Platform
6361 = cxstring::createDup(Avail->getPlatform()->getName());
6362 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6363 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6364 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6365 availability[N].Unavailable = Avail->getUnavailable();
6366 availability[N].Message = cxstring::createDup(Avail->getMessage());
6367 }
6368 ++N;
6369 }
6370 }
6371
6372 if (!HadAvailAttr)
6373 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6374 return getCursorPlatformAvailabilityForDecl(
6375 cast<Decl>(EnumConst->getDeclContext()),
6376 always_deprecated,
6377 deprecated_message,
6378 always_unavailable,
6379 unavailable_message,
6380 availability,
6381 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006382
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006383 return N;
6384}
6385
Guy Benyei11169dd2012-12-18 14:30:41 +00006386int clang_getCursorPlatformAvailability(CXCursor cursor,
6387 int *always_deprecated,
6388 CXString *deprecated_message,
6389 int *always_unavailable,
6390 CXString *unavailable_message,
6391 CXPlatformAvailability *availability,
6392 int availability_size) {
6393 if (always_deprecated)
6394 *always_deprecated = 0;
6395 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006396 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006397 if (always_unavailable)
6398 *always_unavailable = 0;
6399 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006400 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006401
Guy Benyei11169dd2012-12-18 14:30:41 +00006402 if (!clang_isDeclaration(cursor.kind))
6403 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006404
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006405 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006406 if (!D)
6407 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006408
6409 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6410 deprecated_message,
6411 always_unavailable,
6412 unavailable_message,
6413 availability,
6414 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006415}
6416
6417void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6418 clang_disposeString(availability->Platform);
6419 clang_disposeString(availability->Message);
6420}
6421
6422CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6423 if (clang_isDeclaration(cursor.kind))
6424 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6425
6426 return CXLanguage_Invalid;
6427}
6428
6429 /// \brief If the given cursor is the "templated" declaration
6430 /// descibing a class or function template, return the class or
6431 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006432static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006433 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006434 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006435
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006436 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006437 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6438 return FunTmpl;
6439
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006440 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006441 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6442 return ClassTmpl;
6443
6444 return D;
6445}
6446
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006447
6448enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
6449 StorageClass sc = SC_None;
6450 const Decl *D = getCursorDecl(C);
6451 if (D) {
6452 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
6453 sc = FD->getStorageClass();
6454 } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
6455 sc = VD->getStorageClass();
6456 } else {
6457 return CX_SC_Invalid;
6458 }
6459 } else {
6460 return CX_SC_Invalid;
6461 }
6462 switch (sc) {
6463 case SC_None:
6464 return CX_SC_None;
6465 case SC_Extern:
6466 return CX_SC_Extern;
6467 case SC_Static:
6468 return CX_SC_Static;
6469 case SC_PrivateExtern:
6470 return CX_SC_PrivateExtern;
6471 case SC_OpenCLWorkGroupLocal:
6472 return CX_SC_OpenCLWorkGroupLocal;
6473 case SC_Auto:
6474 return CX_SC_Auto;
6475 case SC_Register:
6476 return CX_SC_Register;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006477 }
Kaelyn Takataab61e702014-10-15 18:03:26 +00006478 llvm_unreachable("Unhandled storage class!");
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006479}
6480
Guy Benyei11169dd2012-12-18 14:30:41 +00006481CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6482 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006483 if (const Decl *D = getCursorDecl(cursor)) {
6484 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006485 if (!DC)
6486 return clang_getNullCursor();
6487
6488 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6489 getCursorTU(cursor));
6490 }
6491 }
6492
6493 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006494 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006495 return MakeCXCursor(D, getCursorTU(cursor));
6496 }
6497
6498 return clang_getNullCursor();
6499}
6500
6501CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6502 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006503 if (const Decl *D = getCursorDecl(cursor)) {
6504 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006505 if (!DC)
6506 return clang_getNullCursor();
6507
6508 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6509 getCursorTU(cursor));
6510 }
6511 }
6512
6513 // FIXME: Note that we can't easily compute the lexical context of a
6514 // statement or expression, so we return nothing.
6515 return clang_getNullCursor();
6516}
6517
6518CXFile clang_getIncludedFile(CXCursor cursor) {
6519 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006520 return nullptr;
6521
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006522 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006523 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006524}
6525
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006526unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6527 if (C.kind != CXCursor_ObjCPropertyDecl)
6528 return CXObjCPropertyAttr_noattr;
6529
6530 unsigned Result = CXObjCPropertyAttr_noattr;
6531 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6532 ObjCPropertyDecl::PropertyAttributeKind Attr =
6533 PD->getPropertyAttributesAsWritten();
6534
6535#define SET_CXOBJCPROP_ATTR(A) \
6536 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6537 Result |= CXObjCPropertyAttr_##A
6538 SET_CXOBJCPROP_ATTR(readonly);
6539 SET_CXOBJCPROP_ATTR(getter);
6540 SET_CXOBJCPROP_ATTR(assign);
6541 SET_CXOBJCPROP_ATTR(readwrite);
6542 SET_CXOBJCPROP_ATTR(retain);
6543 SET_CXOBJCPROP_ATTR(copy);
6544 SET_CXOBJCPROP_ATTR(nonatomic);
6545 SET_CXOBJCPROP_ATTR(setter);
6546 SET_CXOBJCPROP_ATTR(atomic);
6547 SET_CXOBJCPROP_ATTR(weak);
6548 SET_CXOBJCPROP_ATTR(strong);
6549 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6550#undef SET_CXOBJCPROP_ATTR
6551
6552 return Result;
6553}
6554
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006555unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6556 if (!clang_isDeclaration(C.kind))
6557 return CXObjCDeclQualifier_None;
6558
6559 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6560 const Decl *D = getCursorDecl(C);
6561 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6562 QT = MD->getObjCDeclQualifier();
6563 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6564 QT = PD->getObjCDeclQualifier();
6565 if (QT == Decl::OBJC_TQ_None)
6566 return CXObjCDeclQualifier_None;
6567
6568 unsigned Result = CXObjCDeclQualifier_None;
6569 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6570 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6571 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6572 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6573 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6574 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6575
6576 return Result;
6577}
6578
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006579unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6580 if (!clang_isDeclaration(C.kind))
6581 return 0;
6582
6583 const Decl *D = getCursorDecl(C);
6584 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6585 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6586 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6587 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6588
6589 return 0;
6590}
6591
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006592unsigned clang_Cursor_isVariadic(CXCursor C) {
6593 if (!clang_isDeclaration(C.kind))
6594 return 0;
6595
6596 const Decl *D = getCursorDecl(C);
6597 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6598 return FD->isVariadic();
6599 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6600 return MD->isVariadic();
6601
6602 return 0;
6603}
6604
Guy Benyei11169dd2012-12-18 14:30:41 +00006605CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6606 if (!clang_isDeclaration(C.kind))
6607 return clang_getNullRange();
6608
6609 const Decl *D = getCursorDecl(C);
6610 ASTContext &Context = getCursorContext(C);
6611 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6612 if (!RC)
6613 return clang_getNullRange();
6614
6615 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6616}
6617
6618CXString clang_Cursor_getRawCommentText(CXCursor C) {
6619 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006620 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006621
6622 const Decl *D = getCursorDecl(C);
6623 ASTContext &Context = getCursorContext(C);
6624 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6625 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6626 StringRef();
6627
6628 // Don't duplicate the string because RawText points directly into source
6629 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006630 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006631}
6632
6633CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6634 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006635 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006636
6637 const Decl *D = getCursorDecl(C);
6638 const ASTContext &Context = getCursorContext(C);
6639 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6640
6641 if (RC) {
6642 StringRef BriefText = RC->getBriefText(Context);
6643
6644 // Don't duplicate the string because RawComment ensures that this memory
6645 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006646 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006647 }
6648
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006649 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006650}
6651
Guy Benyei11169dd2012-12-18 14:30:41 +00006652CXModule clang_Cursor_getModule(CXCursor C) {
6653 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006654 if (const ImportDecl *ImportD =
6655 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006656 return ImportD->getImportedModule();
6657 }
6658
Craig Topper69186e72014-06-08 08:38:04 +00006659 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006660}
6661
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006662CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6663 if (isNotUsableTU(TU)) {
6664 LOG_BAD_TU(TU);
6665 return nullptr;
6666 }
6667 if (!File)
6668 return nullptr;
6669 FileEntry *FE = static_cast<FileEntry *>(File);
6670
6671 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6672 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6673 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6674
Richard Smithfeb54b62014-10-23 02:01:19 +00006675 return Header.getModule();
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006676}
6677
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006678CXFile clang_Module_getASTFile(CXModule CXMod) {
6679 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006680 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006681 Module *Mod = static_cast<Module*>(CXMod);
6682 return const_cast<FileEntry *>(Mod->getASTFile());
6683}
6684
Guy Benyei11169dd2012-12-18 14:30:41 +00006685CXModule clang_Module_getParent(CXModule CXMod) {
6686 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006687 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006688 Module *Mod = static_cast<Module*>(CXMod);
6689 return Mod->Parent;
6690}
6691
6692CXString clang_Module_getName(CXModule CXMod) {
6693 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006694 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006695 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006696 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006697}
6698
6699CXString clang_Module_getFullName(CXModule CXMod) {
6700 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006701 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006702 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006703 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006704}
6705
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006706int clang_Module_isSystem(CXModule CXMod) {
6707 if (!CXMod)
6708 return 0;
6709 Module *Mod = static_cast<Module*>(CXMod);
6710 return Mod->IsSystem;
6711}
6712
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006713unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6714 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006715 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006716 LOG_BAD_TU(TU);
6717 return 0;
6718 }
6719 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006720 return 0;
6721 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006722 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6723 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6724 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006725}
6726
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006727CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6728 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006729 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006730 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006731 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006732 }
6733 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006734 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006735 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006736 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006737
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006738 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6739 if (Index < TopHeaders.size())
6740 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006741
Craig Topper69186e72014-06-08 08:38:04 +00006742 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006743}
6744
6745} // end: extern "C"
6746
6747//===----------------------------------------------------------------------===//
6748// C++ AST instrospection.
6749//===----------------------------------------------------------------------===//
6750
6751extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006752unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6753 if (!clang_isDeclaration(C.kind))
6754 return 0;
6755
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006756 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006757 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006758 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006759 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6760}
6761
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006762unsigned clang_CXXMethod_isConst(CXCursor C) {
6763 if (!clang_isDeclaration(C.kind))
6764 return 0;
6765
6766 const Decl *D = cxcursor::getCursorDecl(C);
6767 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006768 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006769 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6770}
6771
Guy Benyei11169dd2012-12-18 14:30:41 +00006772unsigned clang_CXXMethod_isStatic(CXCursor C) {
6773 if (!clang_isDeclaration(C.kind))
6774 return 0;
6775
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006776 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006777 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006778 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006779 return (Method && Method->isStatic()) ? 1 : 0;
6780}
6781
6782unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6783 if (!clang_isDeclaration(C.kind))
6784 return 0;
6785
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006786 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006787 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006788 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006789 return (Method && Method->isVirtual()) ? 1 : 0;
6790}
6791} // end: extern "C"
6792
6793//===----------------------------------------------------------------------===//
6794// Attribute introspection.
6795//===----------------------------------------------------------------------===//
6796
6797extern "C" {
6798CXType clang_getIBOutletCollectionType(CXCursor C) {
6799 if (C.kind != CXCursor_IBOutletCollectionAttr)
6800 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6801
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006802 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006803 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6804
6805 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6806}
6807} // end: extern "C"
6808
6809//===----------------------------------------------------------------------===//
6810// Inspecting memory usage.
6811//===----------------------------------------------------------------------===//
6812
6813typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6814
6815static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6816 enum CXTUResourceUsageKind k,
6817 unsigned long amount) {
6818 CXTUResourceUsageEntry entry = { k, amount };
6819 entries.push_back(entry);
6820}
6821
6822extern "C" {
6823
6824const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6825 const char *str = "";
6826 switch (kind) {
6827 case CXTUResourceUsage_AST:
6828 str = "ASTContext: expressions, declarations, and types";
6829 break;
6830 case CXTUResourceUsage_Identifiers:
6831 str = "ASTContext: identifiers";
6832 break;
6833 case CXTUResourceUsage_Selectors:
6834 str = "ASTContext: selectors";
6835 break;
6836 case CXTUResourceUsage_GlobalCompletionResults:
6837 str = "Code completion: cached global results";
6838 break;
6839 case CXTUResourceUsage_SourceManagerContentCache:
6840 str = "SourceManager: content cache allocator";
6841 break;
6842 case CXTUResourceUsage_AST_SideTables:
6843 str = "ASTContext: side tables";
6844 break;
6845 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6846 str = "SourceManager: malloc'ed memory buffers";
6847 break;
6848 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6849 str = "SourceManager: mmap'ed memory buffers";
6850 break;
6851 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6852 str = "ExternalASTSource: malloc'ed memory buffers";
6853 break;
6854 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6855 str = "ExternalASTSource: mmap'ed memory buffers";
6856 break;
6857 case CXTUResourceUsage_Preprocessor:
6858 str = "Preprocessor: malloc'ed memory";
6859 break;
6860 case CXTUResourceUsage_PreprocessingRecord:
6861 str = "Preprocessor: PreprocessingRecord";
6862 break;
6863 case CXTUResourceUsage_SourceManager_DataStructures:
6864 str = "SourceManager: data structures and tables";
6865 break;
6866 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6867 str = "Preprocessor: header search tables";
6868 break;
6869 }
6870 return str;
6871}
6872
6873CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006874 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006875 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006876 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00006877 return usage;
6878 }
6879
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006880 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006881 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006882 ASTContext &astContext = astUnit->getASTContext();
6883
6884 // How much memory is used by AST nodes and types?
6885 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6886 (unsigned long) astContext.getASTAllocatedMemory());
6887
6888 // How much memory is used by identifiers?
6889 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6890 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6891
6892 // How much memory is used for selectors?
6893 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6894 (unsigned long) astContext.Selectors.getTotalMemory());
6895
6896 // How much memory is used by ASTContext's side tables?
6897 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6898 (unsigned long) astContext.getSideTableAllocatedMemory());
6899
6900 // How much memory is used for caching global code completion results?
6901 unsigned long completionBytes = 0;
6902 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00006903 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006904 completionBytes = completionAllocator->getTotalMemory();
6905 }
6906 createCXTUResourceUsageEntry(*entries,
6907 CXTUResourceUsage_GlobalCompletionResults,
6908 completionBytes);
6909
6910 // How much memory is being used by SourceManager's content cache?
6911 createCXTUResourceUsageEntry(*entries,
6912 CXTUResourceUsage_SourceManagerContentCache,
6913 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6914
6915 // How much memory is being used by the MemoryBuffer's in SourceManager?
6916 const SourceManager::MemoryBufferSizes &srcBufs =
6917 astUnit->getSourceManager().getMemoryBufferSizes();
6918
6919 createCXTUResourceUsageEntry(*entries,
6920 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6921 (unsigned long) srcBufs.malloc_bytes);
6922 createCXTUResourceUsageEntry(*entries,
6923 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6924 (unsigned long) srcBufs.mmap_bytes);
6925 createCXTUResourceUsageEntry(*entries,
6926 CXTUResourceUsage_SourceManager_DataStructures,
6927 (unsigned long) astContext.getSourceManager()
6928 .getDataStructureSizes());
6929
6930 // How much memory is being used by the ExternalASTSource?
6931 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6932 const ExternalASTSource::MemoryBufferSizes &sizes =
6933 esrc->getMemoryBufferSizes();
6934
6935 createCXTUResourceUsageEntry(*entries,
6936 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6937 (unsigned long) sizes.malloc_bytes);
6938 createCXTUResourceUsageEntry(*entries,
6939 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6940 (unsigned long) sizes.mmap_bytes);
6941 }
6942
6943 // How much memory is being used by the Preprocessor?
6944 Preprocessor &pp = astUnit->getPreprocessor();
6945 createCXTUResourceUsageEntry(*entries,
6946 CXTUResourceUsage_Preprocessor,
6947 pp.getTotalMemory());
6948
6949 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6950 createCXTUResourceUsageEntry(*entries,
6951 CXTUResourceUsage_PreprocessingRecord,
6952 pRec->getTotalMemory());
6953 }
6954
6955 createCXTUResourceUsageEntry(*entries,
6956 CXTUResourceUsage_Preprocessor_HeaderSearch,
6957 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00006958
Guy Benyei11169dd2012-12-18 14:30:41 +00006959 CXTUResourceUsage usage = { (void*) entries.get(),
6960 (unsigned) entries->size(),
Alexander Kornienko6ee521c2015-01-23 15:36:10 +00006961 !entries->empty() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00006962 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00006963 return usage;
6964}
6965
6966void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6967 if (usage.data)
6968 delete (MemUsageEntries*) usage.data;
6969}
6970
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006971CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6972 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006973 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00006974 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006975
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006976 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006977 LOG_BAD_TU(TU);
6978 return skipped;
6979 }
6980
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006981 if (!file)
6982 return skipped;
6983
6984 ASTUnit *astUnit = cxtu::getASTUnit(TU);
6985 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6986 if (!ppRec)
6987 return skipped;
6988
6989 ASTContext &Ctx = astUnit->getASTContext();
6990 SourceManager &sm = Ctx.getSourceManager();
6991 FileEntry *fileEntry = static_cast<FileEntry *>(file);
6992 FileID wantedFileID = sm.translateFile(fileEntry);
6993
6994 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6995 std::vector<SourceRange> wantedRanges;
6996 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6997 i != ei; ++i) {
6998 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6999 wantedRanges.push_back(*i);
7000 }
7001
7002 skipped->count = wantedRanges.size();
7003 skipped->ranges = new CXSourceRange[skipped->count];
7004 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
7005 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
7006
7007 return skipped;
7008}
7009
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007010void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
7011 if (ranges) {
7012 delete[] ranges->ranges;
7013 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007014 }
7015}
7016
Guy Benyei11169dd2012-12-18 14:30:41 +00007017} // end extern "C"
7018
7019void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
7020 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
7021 for (unsigned I = 0; I != Usage.numEntries; ++I)
7022 fprintf(stderr, " %s: %lu\n",
7023 clang_getTUResourceUsageName(Usage.entries[I].kind),
7024 Usage.entries[I].amount);
7025
7026 clang_disposeCXTUResourceUsage(Usage);
7027}
7028
7029//===----------------------------------------------------------------------===//
7030// Misc. utility functions.
7031//===----------------------------------------------------------------------===//
7032
7033/// Default to using an 8 MB stack size on "safety" threads.
7034static unsigned SafetyStackThreadSize = 8 << 20;
7035
7036namespace clang {
7037
7038bool RunSafely(llvm::CrashRecoveryContext &CRC,
7039 void (*Fn)(void*), void *UserData,
7040 unsigned Size) {
7041 if (!Size)
7042 Size = GetSafetyThreadStackSize();
7043 if (Size)
7044 return CRC.RunSafelyOnThread(Fn, UserData, Size);
7045 return CRC.RunSafely(Fn, UserData);
7046}
7047
7048unsigned GetSafetyThreadStackSize() {
7049 return SafetyStackThreadSize;
7050}
7051
7052void SetSafetyThreadStackSize(unsigned Value) {
7053 SafetyStackThreadSize = Value;
7054}
7055
7056}
7057
7058void clang::setThreadBackgroundPriority() {
7059 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
7060 return;
7061
Alp Toker1a86ad22014-07-06 06:24:00 +00007062#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00007063 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
7064#endif
7065}
7066
7067void cxindex::printDiagsToStderr(ASTUnit *Unit) {
7068 if (!Unit)
7069 return;
7070
7071 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
7072 DEnd = Unit->stored_diag_end();
7073 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00007074 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00007075 CXString Msg = clang_formatDiagnostic(&Diag,
7076 clang_defaultDiagnosticDisplayOptions());
7077 fprintf(stderr, "%s\n", clang_getCString(Msg));
7078 clang_disposeString(Msg);
7079 }
7080#ifdef LLVM_ON_WIN32
7081 // On Windows, force a flush, since there may be multiple copies of
7082 // stderr and stdout in the file system, all with different buffers
7083 // but writing to the same device.
7084 fflush(stderr);
7085#endif
7086}
7087
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007088MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
7089 SourceLocation MacroDefLoc,
7090 CXTranslationUnit TU){
7091 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007092 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007093 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007094 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007095
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007096 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007097 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007098 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007099 if (MD) {
7100 for (MacroDirective::DefInfo
7101 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
7102 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
7103 return Def.getMacroInfo();
7104 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007105 }
7106
Craig Topper69186e72014-06-08 08:38:04 +00007107 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007108}
7109
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007110const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
7111 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007112 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007113 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007114 const IdentifierInfo *II = MacroDef->getName();
7115 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00007116 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007117
7118 return getMacroInfo(*II, MacroDef->getLocation(), TU);
7119}
7120
7121MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
7122 const Token &Tok,
7123 CXTranslationUnit TU) {
7124 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007125 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007126 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00007127 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007128
7129 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007130 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007131 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
7132 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007133 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007134
7135 // Check that the token is inside the definition and not its argument list.
7136 SourceManager &SM = Unit->getSourceManager();
7137 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00007138 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007139 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00007140 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007141
7142 Preprocessor &PP = Unit->getPreprocessor();
7143 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
7144 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00007145 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007146
Alp Toker2d57cea2014-05-17 04:53:25 +00007147 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007148 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007149 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007150
7151 // Check that the identifier is not one of the macro arguments.
7152 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00007153 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007154
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007155 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
7156 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00007157 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007158
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007159 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007160}
7161
7162MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
7163 SourceLocation Loc,
7164 CXTranslationUnit TU) {
7165 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007166 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007167
7168 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007169 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007170 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007171 Preprocessor &PP = Unit->getPreprocessor();
7172 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00007173 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007174 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7175 Token Tok;
7176 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00007177 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007178
7179 return checkForMacroInMacroDefinition(MI, Tok, TU);
7180}
7181
Guy Benyei11169dd2012-12-18 14:30:41 +00007182extern "C" {
7183
7184CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007185 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00007186}
7187
7188} // end: extern "C"
7189
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007190Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7191 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007192 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007193 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007194 if (Unit->isMainFileAST())
7195 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007196 return *this;
7197 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007198 } else {
7199 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007200 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007201 return *this;
7202}
7203
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007204Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7205 *this << FE->getName();
7206 return *this;
7207}
7208
7209Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7210 CXString cursorName = clang_getCursorDisplayName(cursor);
7211 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7212 clang_disposeString(cursorName);
7213 return *this;
7214}
7215
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007216Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7217 CXFile File;
7218 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007219 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007220 CXString FileName = clang_getFileName(File);
7221 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7222 clang_disposeString(FileName);
7223 return *this;
7224}
7225
7226Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7227 CXSourceLocation BLoc = clang_getRangeStart(range);
7228 CXSourceLocation ELoc = clang_getRangeEnd(range);
7229
7230 CXFile BFile;
7231 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007232 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007233
7234 CXFile EFile;
7235 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007236 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007237
7238 CXString BFileName = clang_getFileName(BFile);
7239 if (BFile == EFile) {
7240 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7241 BLine, BColumn, ELine, EColumn);
7242 } else {
7243 CXString EFileName = clang_getFileName(EFile);
7244 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7245 BLine, BColumn)
7246 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7247 ELine, EColumn);
7248 clang_disposeString(EFileName);
7249 }
7250 clang_disposeString(BFileName);
7251 return *this;
7252}
7253
7254Logger &cxindex::Logger::operator<<(CXString Str) {
7255 *this << clang_getCString(Str);
7256 return *this;
7257}
7258
7259Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7260 LogOS << Fmt;
7261 return *this;
7262}
7263
Chandler Carruth37ad2582014-06-27 15:14:39 +00007264static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7265
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007266cxindex::Logger::~Logger() {
7267 LogOS.flush();
7268
Chandler Carruth37ad2582014-06-27 15:14:39 +00007269 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007270
7271 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7272
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007273 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007274 OS << "[libclang:" << Name << ':';
7275
Alp Toker1a86ad22014-07-06 06:24:00 +00007276#ifdef USE_DARWIN_THREADS
7277 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007278 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7279 OS << tid << ':';
7280#endif
7281
7282 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7283 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
Yaron Keren09fb7c62015-03-10 07:33:23 +00007284 OS << Msg << '\n';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007285
7286 if (Trace) {
Zachary Turner1fe2a8d2015-03-05 19:15:09 +00007287 llvm::sys::PrintStackTrace(OS);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007288 OS << "--------------------------------------------------\n";
7289 }
7290}