blob: 9729531c0f85c6862174c50bf511d1ac87979abf [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.
2241 if (!M->isImplicitAccess())
2242 AddStmt(M->getBase());
2243}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002244void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002245 AddTypeLoc(E->getEncodedTypeSourceInfo());
2246}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002247void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002248 EnqueueChildren(M);
2249 AddTypeLoc(M->getClassReceiverTypeInfo());
2250}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002251void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002252 // Visit the components of the offsetof expression.
2253 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2254 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2255 const OffsetOfNode &Node = E->getComponent(I-1);
2256 switch (Node.getKind()) {
2257 case OffsetOfNode::Array:
2258 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2259 break;
2260 case OffsetOfNode::Field:
2261 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2262 break;
2263 case OffsetOfNode::Identifier:
2264 case OffsetOfNode::Base:
2265 continue;
2266 }
2267 }
2268 // Visit the type into which we're computing the offset.
2269 AddTypeLoc(E->getTypeSourceInfo());
2270}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002271void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002272 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2273 WL.push_back(OverloadExprParts(E, Parent));
2274}
2275void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002276 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002277 EnqueueChildren(E);
2278 if (E->isArgumentType())
2279 AddTypeLoc(E->getArgumentTypeInfo());
2280}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002281void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002282 EnqueueChildren(S);
2283}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002284void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002285 AddStmt(S->getBody());
2286 AddStmt(S->getCond());
2287 AddDecl(S->getConditionVariable());
2288}
2289
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002290void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002291 AddStmt(W->getBody());
2292 AddStmt(W->getCond());
2293 AddDecl(W->getConditionVariable());
2294}
2295
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002296void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002297 for (unsigned I = E->getNumArgs(); I > 0; --I)
2298 AddTypeLoc(E->getArg(I-1));
2299}
2300
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002301void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002302 AddTypeLoc(E->getQueriedTypeSourceInfo());
2303}
2304
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002305void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002306 EnqueueChildren(E);
2307}
2308
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002309void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002310 VisitOverloadExpr(U);
2311 if (!U->isImplicitAccess())
2312 AddStmt(U->getBase());
2313}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002314void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002315 AddStmt(E->getSubExpr());
2316 AddTypeLoc(E->getWrittenTypeInfo());
2317}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002318void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002319 WL.push_back(SizeOfPackExprParts(E, Parent));
2320}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002321void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002322 // If the opaque value has a source expression, just transparently
2323 // visit that. This is useful for (e.g.) pseudo-object expressions.
2324 if (Expr *SourceExpr = E->getSourceExpr())
2325 return Visit(SourceExpr);
2326}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002327void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002328 AddStmt(E->getBody());
2329 WL.push_back(LambdaExprParts(E, Parent));
2330}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002331void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002332 // Treat the expression like its syntactic form.
2333 Visit(E->getSyntacticForm());
2334}
2335
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002336void EnqueueVisitor::VisitOMPExecutableDirective(
2337 const OMPExecutableDirective *D) {
2338 EnqueueChildren(D);
2339 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2340 E = D->clauses().end();
2341 I != E; ++I)
2342 EnqueueChildren(*I);
2343}
2344
Alexander Musman3aaab662014-08-19 11:27:13 +00002345void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
2346 VisitOMPExecutableDirective(D);
2347}
2348
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002349void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2350 VisitOMPExecutableDirective(D);
2351}
2352
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002353void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002354 VisitOMPLoopDirective(D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002355}
2356
Alexey Bataevf29276e2014-06-18 04:14:57 +00002357void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002358 VisitOMPLoopDirective(D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002359}
2360
Alexander Musmanf82886e2014-09-18 05:12:34 +00002361void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
2362 VisitOMPLoopDirective(D);
2363}
2364
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002365void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2366 VisitOMPExecutableDirective(D);
2367}
2368
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002369void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2370 VisitOMPExecutableDirective(D);
2371}
2372
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002373void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2374 VisitOMPExecutableDirective(D);
2375}
2376
Alexander Musman80c22892014-07-17 08:54:58 +00002377void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2378 VisitOMPExecutableDirective(D);
2379}
2380
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002381void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2382 VisitOMPExecutableDirective(D);
2383 AddDeclarationNameInfo(D);
2384}
2385
Alexey Bataev4acb8592014-07-07 13:01:15 +00002386void
2387EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002388 VisitOMPLoopDirective(D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002389}
2390
Alexander Musmane4e893b2014-09-23 09:33:00 +00002391void EnqueueVisitor::VisitOMPParallelForSimdDirective(
2392 const OMPParallelForSimdDirective *D) {
2393 VisitOMPLoopDirective(D);
2394}
2395
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002396void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2397 const OMPParallelSectionsDirective *D) {
2398 VisitOMPExecutableDirective(D);
2399}
2400
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002401void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2402 VisitOMPExecutableDirective(D);
2403}
2404
Alexey Bataev68446b72014-07-18 07:47:19 +00002405void
2406EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2407 VisitOMPExecutableDirective(D);
2408}
2409
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002410void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2411 VisitOMPExecutableDirective(D);
2412}
2413
Alexey Bataev2df347a2014-07-18 10:17:07 +00002414void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2415 VisitOMPExecutableDirective(D);
2416}
2417
Alexey Bataev6125da92014-07-21 11:26:11 +00002418void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2419 VisitOMPExecutableDirective(D);
2420}
2421
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002422void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2423 VisitOMPExecutableDirective(D);
2424}
2425
Alexey Bataev0162e452014-07-22 10:10:35 +00002426void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2427 VisitOMPExecutableDirective(D);
2428}
2429
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002430void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
2431 VisitOMPExecutableDirective(D);
2432}
2433
Alexey Bataev13314bf2014-10-09 04:18:56 +00002434void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {
2435 VisitOMPExecutableDirective(D);
2436}
2437
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002438void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002439 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2440}
2441
2442bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2443 if (RegionOfInterest.isValid()) {
2444 SourceRange Range = getRawCursorExtent(C);
2445 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2446 return false;
2447 }
2448 return true;
2449}
2450
2451bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2452 while (!WL.empty()) {
2453 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002454 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002455
2456 // Set the Parent field, then back to its old value once we're done.
2457 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2458
2459 switch (LI.getKind()) {
2460 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002461 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002462 if (!D)
2463 continue;
2464
2465 // For now, perform default visitation for Decls.
2466 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2467 cast<DeclVisit>(&LI)->isFirst())))
2468 return true;
2469
2470 continue;
2471 }
2472 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2473 const ASTTemplateArgumentListInfo *ArgList =
2474 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2475 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2476 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2477 Arg != ArgEnd; ++Arg) {
2478 if (VisitTemplateArgumentLoc(*Arg))
2479 return true;
2480 }
2481 continue;
2482 }
2483 case VisitorJob::TypeLocVisitKind: {
2484 // Perform default visitation for TypeLocs.
2485 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2486 return true;
2487 continue;
2488 }
2489 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002490 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002491 if (LabelStmt *stmt = LS->getStmt()) {
2492 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2493 TU))) {
2494 return true;
2495 }
2496 }
2497 continue;
2498 }
2499
2500 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2501 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2502 if (VisitNestedNameSpecifierLoc(V->get()))
2503 return true;
2504 continue;
2505 }
2506
2507 case VisitorJob::DeclarationNameInfoVisitKind: {
2508 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2509 ->get()))
2510 return true;
2511 continue;
2512 }
2513 case VisitorJob::MemberRefVisitKind: {
2514 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2515 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2516 return true;
2517 continue;
2518 }
2519 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002520 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002521 if (!S)
2522 continue;
2523
2524 // Update the current cursor.
2525 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2526 if (!IsInRegionOfInterest(Cursor))
2527 continue;
2528 switch (Visitor(Cursor, Parent, ClientData)) {
2529 case CXChildVisit_Break: return true;
2530 case CXChildVisit_Continue: break;
2531 case CXChildVisit_Recurse:
2532 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002533 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002534 EnqueueWorkList(WL, S);
2535 break;
2536 }
2537 continue;
2538 }
2539 case VisitorJob::MemberExprPartsKind: {
2540 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002541 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002542
2543 // Visit the nested-name-specifier
2544 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2545 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2546 return true;
2547
2548 // Visit the declaration name.
2549 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2550 return true;
2551
2552 // Visit the explicitly-specified template arguments, if any.
2553 if (M->hasExplicitTemplateArgs()) {
2554 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2555 *ArgEnd = Arg + M->getNumTemplateArgs();
2556 Arg != ArgEnd; ++Arg) {
2557 if (VisitTemplateArgumentLoc(*Arg))
2558 return true;
2559 }
2560 }
2561 continue;
2562 }
2563 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002564 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002565 // Visit nested-name-specifier, if present.
2566 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2567 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2568 return true;
2569 // Visit declaration name.
2570 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2571 return true;
2572 continue;
2573 }
2574 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002575 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002576 // Visit the nested-name-specifier.
2577 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2578 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2579 return true;
2580 // Visit the declaration name.
2581 if (VisitDeclarationNameInfo(O->getNameInfo()))
2582 return true;
2583 // Visit the overloaded declaration reference.
2584 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2585 return true;
2586 continue;
2587 }
2588 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002589 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002590 NamedDecl *Pack = E->getPack();
2591 if (isa<TemplateTypeParmDecl>(Pack)) {
2592 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2593 E->getPackLoc(), TU)))
2594 return true;
2595
2596 continue;
2597 }
2598
2599 if (isa<TemplateTemplateParmDecl>(Pack)) {
2600 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2601 E->getPackLoc(), TU)))
2602 return true;
2603
2604 continue;
2605 }
2606
2607 // Non-type template parameter packs and function parameter packs are
2608 // treated like DeclRefExpr cursors.
2609 continue;
2610 }
2611
2612 case VisitorJob::LambdaExprPartsKind: {
2613 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002614 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002615 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2616 CEnd = E->explicit_capture_end();
2617 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002618 // FIXME: Lambda init-captures.
2619 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002620 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002621
Guy Benyei11169dd2012-12-18 14:30:41 +00002622 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2623 C->getLocation(),
2624 TU)))
2625 return true;
2626 }
2627
2628 // Visit parameters and return type, if present.
2629 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2630 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2631 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2632 // Visit the whole type.
2633 if (Visit(TL))
2634 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002635 } else if (FunctionProtoTypeLoc Proto =
2636 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002637 if (E->hasExplicitParameters()) {
2638 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002639 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2640 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002641 return true;
2642 } else {
2643 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002644 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002645 return true;
2646 }
2647 }
2648 }
2649 break;
2650 }
2651
2652 case VisitorJob::PostChildrenVisitKind:
2653 if (PostChildrenVisitor(Parent, ClientData))
2654 return true;
2655 break;
2656 }
2657 }
2658 return false;
2659}
2660
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002661bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002662 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002663 if (!WorkListFreeList.empty()) {
2664 WL = WorkListFreeList.back();
2665 WL->clear();
2666 WorkListFreeList.pop_back();
2667 }
2668 else {
2669 WL = new VisitorWorkList();
2670 WorkListCache.push_back(WL);
2671 }
2672 EnqueueWorkList(*WL, S);
2673 bool result = RunVisitorWorkList(*WL);
2674 WorkListFreeList.push_back(WL);
2675 return result;
2676}
2677
2678namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002679typedef SmallVector<SourceRange, 4> RefNamePieces;
Craig Topper69186e72014-06-08 08:38:04 +00002680RefNamePieces
2681buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2682 const DeclarationNameInfo &NI, const SourceRange &QLoc,
2683 const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002684 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2685 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2686 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2687
2688 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2689
2690 RefNamePieces Pieces;
2691
2692 if (WantQualifier && QLoc.isValid())
2693 Pieces.push_back(QLoc);
2694
2695 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2696 Pieces.push_back(NI.getLoc());
2697
2698 if (WantTemplateArgs && TemplateArgs)
2699 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2700 TemplateArgs->RAngleLoc));
2701
2702 if (Kind == DeclarationName::CXXOperatorName) {
2703 Pieces.push_back(SourceLocation::getFromRawEncoding(
2704 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2705 Pieces.push_back(SourceLocation::getFromRawEncoding(
2706 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2707 }
2708
2709 if (WantSinglePiece) {
2710 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2711 Pieces.clear();
2712 Pieces.push_back(R);
2713 }
2714
2715 return Pieces;
2716}
2717}
2718
2719//===----------------------------------------------------------------------===//
2720// Misc. API hooks.
2721//===----------------------------------------------------------------------===//
2722
Chad Rosier05c71aa2013-03-27 18:28:23 +00002723static void fatal_error_handler(void *user_data, const std::string& reason,
2724 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002725 // Write the result out to stderr avoiding errs() because raw_ostreams can
2726 // call report_fatal_error.
2727 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2728 ::abort();
2729}
2730
Chandler Carruth66660742014-06-27 16:37:27 +00002731namespace {
2732struct RegisterFatalErrorHandler {
2733 RegisterFatalErrorHandler() {
2734 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2735 }
2736};
2737}
2738
2739static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
2740
Guy Benyei11169dd2012-12-18 14:30:41 +00002741extern "C" {
2742CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2743 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002744 // We use crash recovery to make some of our APIs more reliable, implicitly
2745 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002746 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2747 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002748
Chandler Carruth66660742014-06-27 16:37:27 +00002749 // Look through the managed static to trigger construction of the managed
2750 // static which registers our fatal error handler. This ensures it is only
2751 // registered once.
2752 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00002753
2754 CIndexer *CIdxr = new CIndexer();
2755 if (excludeDeclarationsFromPCH)
2756 CIdxr->setOnlyLocalDecls();
2757 if (displayDiagnostics)
2758 CIdxr->setDisplayDiagnostics();
2759
2760 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2761 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2762 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2763 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2764 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2765 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2766
2767 return CIdxr;
2768}
2769
2770void clang_disposeIndex(CXIndex CIdx) {
2771 if (CIdx)
2772 delete static_cast<CIndexer *>(CIdx);
2773}
2774
2775void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2776 if (CIdx)
2777 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2778}
2779
2780unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2781 if (CIdx)
2782 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2783 return 0;
2784}
2785
2786void clang_toggleCrashRecovery(unsigned isEnabled) {
2787 if (isEnabled)
2788 llvm::CrashRecoveryContext::Enable();
2789 else
2790 llvm::CrashRecoveryContext::Disable();
2791}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002792
Guy Benyei11169dd2012-12-18 14:30:41 +00002793CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2794 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002795 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002796 enum CXErrorCode Result =
2797 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002798 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002799 assert((TU && Result == CXError_Success) ||
2800 (!TU && Result != CXError_Success));
2801 return TU;
2802}
2803
2804enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2805 const char *ast_filename,
2806 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002807 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002808 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002809
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002810 if (!CIdx || !ast_filename || !out_TU)
2811 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002812
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002813 LOG_FUNC_SECTION {
2814 *Log << ast_filename;
2815 }
2816
Guy Benyei11169dd2012-12-18 14:30:41 +00002817 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2818 FileSystemOptions FileSystemOpts;
2819
Justin Bognerd512c1e2014-10-15 00:33:06 +00002820 IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
2821 CompilerInstance::createDiagnostics(new DiagnosticOptions());
David Blaikie6f7382d2014-08-10 19:08:04 +00002822 std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
2823 ast_filename, Diags, FileSystemOpts, CXXIdx->getOnlyLocalDecls(), None,
2824 /*CaptureDiagnostics=*/true,
2825 /*AllowPCHWithCompilerErrors=*/true,
2826 /*UserFilesAreVolatile=*/true);
2827 *out_TU = MakeCXTranslationUnit(CXXIdx, AU.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002828 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002829}
2830
2831unsigned clang_defaultEditingTranslationUnitOptions() {
2832 return CXTranslationUnit_PrecompiledPreamble |
2833 CXTranslationUnit_CacheCompletionResults;
2834}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002835
Guy Benyei11169dd2012-12-18 14:30:41 +00002836CXTranslationUnit
2837clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2838 const char *source_filename,
2839 int num_command_line_args,
2840 const char * const *command_line_args,
2841 unsigned num_unsaved_files,
2842 struct CXUnsavedFile *unsaved_files) {
2843 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2844 return clang_parseTranslationUnit(CIdx, source_filename,
2845 command_line_args, num_command_line_args,
2846 unsaved_files, num_unsaved_files,
2847 Options);
2848}
2849
2850struct ParseTranslationUnitInfo {
2851 CXIndex CIdx;
2852 const char *source_filename;
2853 const char *const *command_line_args;
2854 int num_command_line_args;
Alp Toker9d85b182014-07-07 01:23:14 +00002855 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00002856 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002857 CXTranslationUnit *out_TU;
Alp Toker5c532982014-07-07 22:42:03 +00002858 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002859};
2860static void clang_parseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00002861 const ParseTranslationUnitInfo *PTUI =
2862 static_cast<ParseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00002863 CXIndex CIdx = PTUI->CIdx;
2864 const char *source_filename = PTUI->source_filename;
2865 const char * const *command_line_args = PTUI->command_line_args;
2866 int num_command_line_args = PTUI->num_command_line_args;
Guy Benyei11169dd2012-12-18 14:30:41 +00002867 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002868 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002869
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002870 // Set up the initial return values.
2871 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002872 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002873
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002874 // Check arguments.
Alp Toker9d85b182014-07-07 01:23:14 +00002875 if (!CIdx || !out_TU) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002876 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002877 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002878 }
2879
Guy Benyei11169dd2012-12-18 14:30:41 +00002880 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2881
2882 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2883 setThreadBackgroundPriority();
2884
2885 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2886 // FIXME: Add a flag for modules.
2887 TranslationUnitKind TUKind
2888 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002889 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002890 = options & CXTranslationUnit_CacheCompletionResults;
2891 bool IncludeBriefCommentsInCodeCompletion
2892 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2893 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2894 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2895
2896 // Configure the diagnostics.
2897 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002898 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002899
2900 // Recover resources if we crash before exiting this function.
2901 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2902 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00002903 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00002904
Ahmed Charlesb8984322014-03-07 20:03:18 +00002905 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
2906 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002907
2908 // Recover resources if we crash before exiting this function.
2909 llvm::CrashRecoveryContextCleanupRegistrar<
2910 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2911
Alp Toker9d85b182014-07-07 01:23:14 +00002912 for (auto &UF : PTUI->unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00002913 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00002914 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00002915 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00002916 }
2917
Ahmed Charlesb8984322014-03-07 20:03:18 +00002918 std::unique_ptr<std::vector<const char *>> Args(
2919 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002920
2921 // Recover resources if we crash before exiting this method.
2922 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2923 ArgsCleanup(Args.get());
2924
2925 // Since the Clang C library is primarily used by batch tools dealing with
2926 // (often very broken) source code, where spell-checking can have a
2927 // significant negative impact on performance (particularly when
2928 // precompiled headers are involved), we disable it by default.
2929 // Only do this if we haven't found a spell-checking-related argument.
2930 bool FoundSpellCheckingArgument = false;
2931 for (int I = 0; I != num_command_line_args; ++I) {
2932 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2933 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2934 FoundSpellCheckingArgument = true;
2935 break;
2936 }
2937 }
2938 if (!FoundSpellCheckingArgument)
2939 Args->push_back("-fno-spell-checking");
2940
2941 Args->insert(Args->end(), command_line_args,
2942 command_line_args + num_command_line_args);
2943
2944 // The 'source_filename' argument is optional. If the caller does not
2945 // specify it then it is assumed that the source file is specified
2946 // in the actual argument list.
2947 // Put the source file after command_line_args otherwise if '-x' flag is
2948 // present it will be unused.
2949 if (source_filename)
2950 Args->push_back(source_filename);
2951
2952 // Do we need the detailed preprocessing record?
2953 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2954 Args->push_back("-Xclang");
2955 Args->push_back("-detailed-preprocessing-record");
2956 }
2957
2958 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00002959 std::unique_ptr<ASTUnit> ErrUnit;
2960 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Dmitri Gribenko340dd512014-03-12 15:35:53 +00002961 Args->data(), Args->data() + Args->size(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00002962 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
2963 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
2964 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
2965 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
2966 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
2967 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00002968
2969 if (NumErrors != Diags->getClient()->getNumErrors()) {
2970 // Make sure to check that 'Unit' is non-NULL.
2971 if (CXXIdx->getDisplayDiagnostics())
2972 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2973 }
2974
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002975 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
2976 PTUI->result = CXError_ASTReadError;
2977 } else {
Ahmed Charles9a16beb2014-03-07 19:33:25 +00002978 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002979 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
2980 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002981}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002982
2983CXTranslationUnit
2984clang_parseTranslationUnit(CXIndex CIdx,
2985 const char *source_filename,
2986 const char *const *command_line_args,
2987 int num_command_line_args,
2988 struct CXUnsavedFile *unsaved_files,
2989 unsigned num_unsaved_files,
2990 unsigned options) {
2991 CXTranslationUnit TU;
2992 enum CXErrorCode Result = clang_parseTranslationUnit2(
2993 CIdx, source_filename, command_line_args, num_command_line_args,
2994 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00002995 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002996 assert((TU && Result == CXError_Success) ||
2997 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002998 return TU;
2999}
3000
3001enum CXErrorCode clang_parseTranslationUnit2(
3002 CXIndex CIdx,
3003 const char *source_filename,
3004 const char *const *command_line_args,
3005 int num_command_line_args,
3006 struct CXUnsavedFile *unsaved_files,
3007 unsigned num_unsaved_files,
3008 unsigned options,
3009 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003010 LOG_FUNC_SECTION {
3011 *Log << source_filename << ": ";
3012 for (int i = 0; i != num_command_line_args; ++i)
3013 *Log << command_line_args[i] << " ";
3014 }
3015
Alp Toker9d85b182014-07-07 01:23:14 +00003016 if (num_unsaved_files && !unsaved_files)
3017 return CXError_InvalidArguments;
3018
Alp Toker5c532982014-07-07 22:42:03 +00003019 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00003020 ParseTranslationUnitInfo PTUI = {
3021 CIdx,
3022 source_filename,
3023 command_line_args,
3024 num_command_line_args,
3025 llvm::makeArrayRef(unsaved_files, num_unsaved_files),
3026 options,
3027 out_TU,
Alp Toker5c532982014-07-07 22:42:03 +00003028 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00003029 llvm::CrashRecoveryContext CRC;
3030
3031 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
3032 fprintf(stderr, "libclang: crash detected during parsing: {\n");
3033 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3034 fprintf(stderr, " 'command_line_args' : [");
3035 for (int i = 0; i != num_command_line_args; ++i) {
3036 if (i)
3037 fprintf(stderr, ", ");
3038 fprintf(stderr, "'%s'", command_line_args[i]);
3039 }
3040 fprintf(stderr, "],\n");
3041 fprintf(stderr, " 'unsaved_files' : [");
3042 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3043 if (i)
3044 fprintf(stderr, ", ");
3045 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3046 unsaved_files[i].Length);
3047 }
3048 fprintf(stderr, "],\n");
3049 fprintf(stderr, " 'options' : %d,\n", options);
3050 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003051
3052 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003053 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003054 if (CXTranslationUnit *TU = PTUI.out_TU)
3055 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003056 }
Alp Toker5c532982014-07-07 22:42:03 +00003057
3058 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003059}
3060
3061unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
3062 return CXSaveTranslationUnit_None;
3063}
3064
3065namespace {
3066
3067struct SaveTranslationUnitInfo {
3068 CXTranslationUnit TU;
3069 const char *FileName;
3070 unsigned options;
3071 CXSaveError result;
3072};
3073
3074}
3075
3076static void clang_saveTranslationUnit_Impl(void *UserData) {
3077 SaveTranslationUnitInfo *STUI =
3078 static_cast<SaveTranslationUnitInfo*>(UserData);
3079
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003080 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003081 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3082 setThreadBackgroundPriority();
3083
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003084 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00003085 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
3086}
3087
3088int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3089 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003090 LOG_FUNC_SECTION {
3091 *Log << TU << ' ' << FileName;
3092 }
3093
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003094 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003095 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003096 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003097 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003098
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003099 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003100 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3101 if (!CXXUnit->hasSema())
3102 return CXSaveError_InvalidTU;
3103
3104 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
3105
3106 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3107 getenv("LIBCLANG_NOTHREADS")) {
3108 clang_saveTranslationUnit_Impl(&STUI);
3109
3110 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3111 PrintLibclangResourceUsage(TU);
3112
3113 return STUI.result;
3114 }
3115
3116 // We have an AST that has invalid nodes due to compiler errors.
3117 // Use a crash recovery thread for protection.
3118
3119 llvm::CrashRecoveryContext CRC;
3120
3121 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
3122 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3123 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3124 fprintf(stderr, " 'options' : %d,\n", options);
3125 fprintf(stderr, "}\n");
3126
3127 return CXSaveError_Unknown;
3128
3129 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3130 PrintLibclangResourceUsage(TU);
3131 }
3132
3133 return STUI.result;
3134}
3135
3136void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3137 if (CTUnit) {
3138 // If the translation unit has been marked as unsafe to free, just discard
3139 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003140 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3141 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003142 return;
3143
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003144 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003145 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003146 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3147 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003148 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003149 delete CTUnit;
3150 }
3151}
3152
3153unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3154 return CXReparse_None;
3155}
3156
3157struct ReparseTranslationUnitInfo {
3158 CXTranslationUnit TU;
Alp Toker9d85b182014-07-07 01:23:14 +00003159 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00003160 unsigned options;
Alp Toker5c532982014-07-07 22:42:03 +00003161 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003162};
3163
3164static void clang_reparseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00003165 const ReparseTranslationUnitInfo *RTUI =
3166 static_cast<ReparseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00003167 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003168 unsigned options = RTUI->options;
3169 (void) options;
3170
3171 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003172 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003173 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003174 RTUI->result = CXError_InvalidArguments;
3175 return;
3176 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003177
3178 // Reset the associated diagnostics.
3179 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003180 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003181
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003182 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003183 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3184 setThreadBackgroundPriority();
3185
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003186 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003187 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003188
3189 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3190 new std::vector<ASTUnit::RemappedFile>());
3191
Guy Benyei11169dd2012-12-18 14:30:41 +00003192 // Recover resources if we crash before exiting this function.
3193 llvm::CrashRecoveryContextCleanupRegistrar<
3194 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003195
3196 for (auto &UF : RTUI->unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003197 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003198 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003199 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003200 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003201
Dmitri Gribenko2febd212014-02-07 15:00:22 +00003202 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003203 RTUI->result = CXError_Success;
3204 else if (isASTReadError(CXXUnit))
3205 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003206}
3207
3208int clang_reparseTranslationUnit(CXTranslationUnit TU,
3209 unsigned num_unsaved_files,
3210 struct CXUnsavedFile *unsaved_files,
3211 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003212 LOG_FUNC_SECTION {
3213 *Log << TU;
3214 }
3215
Alp Toker9d85b182014-07-07 01:23:14 +00003216 if (num_unsaved_files && !unsaved_files)
3217 return CXError_InvalidArguments;
3218
Alp Toker5c532982014-07-07 22:42:03 +00003219 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00003220 ReparseTranslationUnitInfo RTUI = {
3221 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options,
Alp Toker5c532982014-07-07 22:42:03 +00003222 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00003223
3224 if (getenv("LIBCLANG_NOTHREADS")) {
3225 clang_reparseTranslationUnit_Impl(&RTUI);
Alp Toker5c532982014-07-07 22:42:03 +00003226 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003227 }
3228
3229 llvm::CrashRecoveryContext CRC;
3230
3231 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3232 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003233 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003234 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003235 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3236 PrintLibclangResourceUsage(TU);
3237
Alp Toker5c532982014-07-07 22:42:03 +00003238 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003239}
3240
3241
3242CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003243 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003244 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003245 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003246 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003247
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003248 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003249 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003250}
3251
3252CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003253 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003254 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003255 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003256 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003257
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003258 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003259 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3260}
3261
3262} // end: extern "C"
3263
3264//===----------------------------------------------------------------------===//
3265// CXFile Operations.
3266//===----------------------------------------------------------------------===//
3267
3268extern "C" {
3269CXString clang_getFileName(CXFile SFile) {
3270 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003271 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003272
3273 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003274 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003275}
3276
3277time_t clang_getFileTime(CXFile SFile) {
3278 if (!SFile)
3279 return 0;
3280
3281 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3282 return FEnt->getModificationTime();
3283}
3284
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003285CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003286 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003287 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003288 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003289 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003290
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003291 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003292
3293 FileManager &FMgr = CXXUnit->getFileManager();
3294 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3295}
3296
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003297unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3298 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003299 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003300 LOG_BAD_TU(TU);
3301 return 0;
3302 }
3303
3304 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003305 return 0;
3306
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003307 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003308 FileEntry *FEnt = static_cast<FileEntry *>(file);
3309 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3310 .isFileMultipleIncludeGuarded(FEnt);
3311}
3312
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003313int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3314 if (!file || !outID)
3315 return 1;
3316
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003317 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003318 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3319 outID->data[0] = ID.getDevice();
3320 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003321 outID->data[2] = FEnt->getModificationTime();
3322 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003323}
3324
Argyrios Kyrtzidisac3997e2014-08-16 00:26:19 +00003325int clang_File_isEqual(CXFile file1, CXFile file2) {
3326 if (file1 == file2)
3327 return true;
3328
3329 if (!file1 || !file2)
3330 return false;
3331
3332 FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
3333 FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
3334 return FEnt1->getUniqueID() == FEnt2->getUniqueID();
3335}
3336
Guy Benyei11169dd2012-12-18 14:30:41 +00003337} // end: extern "C"
3338
3339//===----------------------------------------------------------------------===//
3340// CXCursor Operations.
3341//===----------------------------------------------------------------------===//
3342
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003343static const Decl *getDeclFromExpr(const Stmt *E) {
3344 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003345 return getDeclFromExpr(CE->getSubExpr());
3346
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003347 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003348 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003349 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003350 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003351 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003352 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003353 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003354 if (PRE->isExplicitProperty())
3355 return PRE->getExplicitProperty();
3356 // It could be messaging both getter and setter as in:
3357 // ++myobj.myprop;
3358 // in which case prefer to associate the setter since it is less obvious
3359 // from inspecting the source that the setter is going to get called.
3360 if (PRE->isMessagingSetter())
3361 return PRE->getImplicitPropertySetter();
3362 return PRE->getImplicitPropertyGetter();
3363 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003364 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003365 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003366 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003367 if (Expr *Src = OVE->getSourceExpr())
3368 return getDeclFromExpr(Src);
3369
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003370 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003371 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003372 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003373 if (!CE->isElidable())
3374 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003375 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003376 return OME->getMethodDecl();
3377
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003378 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003379 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003380 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003381 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3382 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003383 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003384 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3385 isa<ParmVarDecl>(SizeOfPack->getPack()))
3386 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003387
3388 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003389}
3390
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003391static SourceLocation getLocationFromExpr(const Expr *E) {
3392 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003393 return getLocationFromExpr(CE->getSubExpr());
3394
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003395 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003396 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003397 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003398 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003399 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003400 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003401 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003402 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003403 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003404 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003405 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003406 return PropRef->getLocation();
3407
3408 return E->getLocStart();
3409}
3410
3411extern "C" {
3412
3413unsigned clang_visitChildren(CXCursor parent,
3414 CXCursorVisitor visitor,
3415 CXClientData client_data) {
3416 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3417 /*VisitPreprocessorLast=*/false);
3418 return CursorVis.VisitChildren(parent);
3419}
3420
3421#ifndef __has_feature
3422#define __has_feature(x) 0
3423#endif
3424#if __has_feature(blocks)
3425typedef enum CXChildVisitResult
3426 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3427
3428static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3429 CXClientData client_data) {
3430 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3431 return block(cursor, parent);
3432}
3433#else
3434// If we are compiled with a compiler that doesn't have native blocks support,
3435// define and call the block manually, so the
3436typedef struct _CXChildVisitResult
3437{
3438 void *isa;
3439 int flags;
3440 int reserved;
3441 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3442 CXCursor);
3443} *CXCursorVisitorBlock;
3444
3445static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3446 CXClientData client_data) {
3447 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3448 return block->invoke(block, cursor, parent);
3449}
3450#endif
3451
3452
3453unsigned clang_visitChildrenWithBlock(CXCursor parent,
3454 CXCursorVisitorBlock block) {
3455 return clang_visitChildren(parent, visitWithBlock, block);
3456}
3457
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003458static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003459 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003460 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003461
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003462 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003463 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003464 if (const ObjCPropertyImplDecl *PropImpl =
3465 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003466 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003467 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003468
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003469 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003470 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003471 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003472
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003473 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003474 }
3475
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003476 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003477 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003478
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003479 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003480 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3481 // and returns different names. NamedDecl returns the class name and
3482 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003483 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003484
3485 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003486 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003487
3488 SmallString<1024> S;
3489 llvm::raw_svector_ostream os(S);
3490 ND->printName(os);
3491
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003492 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003493}
3494
3495CXString clang_getCursorSpelling(CXCursor C) {
3496 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003497 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003498
3499 if (clang_isReference(C.kind)) {
3500 switch (C.kind) {
3501 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003502 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003503 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003504 }
3505 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003506 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003507 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003508 }
3509 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003510 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003511 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003512 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003513 }
3514 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003515 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003516 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003517 }
3518 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003519 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003520 assert(Type && "Missing type decl");
3521
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003522 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003523 getAsString());
3524 }
3525 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003526 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003527 assert(Template && "Missing template decl");
3528
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003529 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003530 }
3531
3532 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003533 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003534 assert(NS && "Missing namespace decl");
3535
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003536 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003537 }
3538
3539 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003540 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003541 assert(Field && "Missing member decl");
3542
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003543 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003544 }
3545
3546 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003547 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003548 assert(Label && "Missing label");
3549
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003550 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003551 }
3552
3553 case CXCursor_OverloadedDeclRef: {
3554 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003555 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3556 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003557 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003558 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003559 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003560 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003561 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003562 OverloadedTemplateStorage *Ovl
3563 = Storage.get<OverloadedTemplateStorage*>();
3564 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003565 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003566 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003567 }
3568
3569 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003570 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003571 assert(Var && "Missing variable decl");
3572
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003573 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003574 }
3575
3576 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003577 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003578 }
3579 }
3580
3581 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003582 const Expr *E = getCursorExpr(C);
3583
3584 if (C.kind == CXCursor_ObjCStringLiteral ||
3585 C.kind == CXCursor_StringLiteral) {
3586 const StringLiteral *SLit;
3587 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3588 SLit = OSL->getString();
3589 } else {
3590 SLit = cast<StringLiteral>(E);
3591 }
3592 SmallString<256> Buf;
3593 llvm::raw_svector_ostream OS(Buf);
3594 SLit->outputString(OS);
3595 return cxstring::createDup(OS.str());
3596 }
3597
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003598 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003599 if (D)
3600 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003601 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003602 }
3603
3604 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003605 const Stmt *S = getCursorStmt(C);
3606 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003607 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003608
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003609 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003610 }
3611
3612 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003613 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003614 ->getNameStart());
3615
3616 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003617 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003618 ->getNameStart());
3619
3620 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003621 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003622
3623 if (clang_isDeclaration(C.kind))
3624 return getDeclSpelling(getCursorDecl(C));
3625
3626 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003627 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003628 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003629 }
3630
3631 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003632 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003633 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003634 }
3635
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003636 if (C.kind == CXCursor_PackedAttr) {
3637 return cxstring::createRef("packed");
3638 }
3639
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003640 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003641}
3642
3643CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3644 unsigned pieceIndex,
3645 unsigned options) {
3646 if (clang_Cursor_isNull(C))
3647 return clang_getNullRange();
3648
3649 ASTContext &Ctx = getCursorContext(C);
3650
3651 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003652 const Stmt *S = getCursorStmt(C);
3653 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003654 if (pieceIndex > 0)
3655 return clang_getNullRange();
3656 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3657 }
3658
3659 return clang_getNullRange();
3660 }
3661
3662 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003663 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003664 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3665 if (pieceIndex >= ME->getNumSelectorLocs())
3666 return clang_getNullRange();
3667 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3668 }
3669 }
3670
3671 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3672 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003673 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003674 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3675 if (pieceIndex >= MD->getNumSelectorLocs())
3676 return clang_getNullRange();
3677 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3678 }
3679 }
3680
3681 if (C.kind == CXCursor_ObjCCategoryDecl ||
3682 C.kind == CXCursor_ObjCCategoryImplDecl) {
3683 if (pieceIndex > 0)
3684 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003685 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003686 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3687 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003688 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003689 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3690 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3691 }
3692
3693 if (C.kind == CXCursor_ModuleImportDecl) {
3694 if (pieceIndex > 0)
3695 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003696 if (const ImportDecl *ImportD =
3697 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003698 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3699 if (!Locs.empty())
3700 return cxloc::translateSourceRange(Ctx,
3701 SourceRange(Locs.front(), Locs.back()));
3702 }
3703 return clang_getNullRange();
3704 }
3705
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00003706 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
3707 C.kind == CXCursor_ConversionFunction) {
3708 if (pieceIndex > 0)
3709 return clang_getNullRange();
3710 if (const FunctionDecl *FD =
3711 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
3712 DeclarationNameInfo FunctionName = FD->getNameInfo();
3713 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
3714 }
3715 return clang_getNullRange();
3716 }
3717
Guy Benyei11169dd2012-12-18 14:30:41 +00003718 // FIXME: A CXCursor_InclusionDirective should give the location of the
3719 // filename, but we don't keep track of this.
3720
3721 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3722 // but we don't keep track of this.
3723
3724 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3725 // but we don't keep track of this.
3726
3727 // Default handling, give the location of the cursor.
3728
3729 if (pieceIndex > 0)
3730 return clang_getNullRange();
3731
3732 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3733 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3734 return cxloc::translateSourceRange(Ctx, Loc);
3735}
3736
Eli Bendersky44a206f2014-07-31 18:04:56 +00003737CXString clang_Cursor_getMangling(CXCursor C) {
3738 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
3739 return cxstring::createEmpty();
3740
Eli Bendersky44a206f2014-07-31 18:04:56 +00003741 // Mangling only works for functions and variables.
Eli Bendersky79759592014-08-01 15:01:10 +00003742 const Decl *D = getCursorDecl(C);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003743 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
3744 return cxstring::createEmpty();
3745
Eli Bendersky79759592014-08-01 15:01:10 +00003746 // First apply frontend mangling.
Eli Bendersky44a206f2014-07-31 18:04:56 +00003747 const NamedDecl *ND = cast<NamedDecl>(D);
Eli Bendersky79759592014-08-01 15:01:10 +00003748 ASTContext &Ctx = ND->getASTContext();
3749 std::unique_ptr<MangleContext> MC(Ctx.createMangleContext());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003750
Eli Bendersky79759592014-08-01 15:01:10 +00003751 std::string FrontendBuf;
3752 llvm::raw_string_ostream FrontendBufOS(FrontendBuf);
3753 MC->mangleName(ND, FrontendBufOS);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003754
Eli Bendersky79759592014-08-01 15:01:10 +00003755 // Now apply backend mangling.
3756 std::unique_ptr<llvm::DataLayout> DL(
3757 new llvm::DataLayout(Ctx.getTargetInfo().getTargetDescription()));
3758 llvm::Mangler BackendMangler(DL.get());
3759
3760 std::string FinalBuf;
3761 llvm::raw_string_ostream FinalBufOS(FinalBuf);
3762 BackendMangler.getNameWithPrefix(FinalBufOS,
3763 llvm::Twine(FrontendBufOS.str()));
3764
3765 return cxstring::createDup(FinalBufOS.str());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003766}
3767
Guy Benyei11169dd2012-12-18 14:30:41 +00003768CXString clang_getCursorDisplayName(CXCursor C) {
3769 if (!clang_isDeclaration(C.kind))
3770 return clang_getCursorSpelling(C);
3771
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003772 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003773 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003774 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003775
3776 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003777 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003778 D = FunTmpl->getTemplatedDecl();
3779
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003780 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003781 SmallString<64> Str;
3782 llvm::raw_svector_ostream OS(Str);
3783 OS << *Function;
3784 if (Function->getPrimaryTemplate())
3785 OS << "<>";
3786 OS << "(";
3787 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3788 if (I)
3789 OS << ", ";
3790 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3791 }
3792
3793 if (Function->isVariadic()) {
3794 if (Function->getNumParams())
3795 OS << ", ";
3796 OS << "...";
3797 }
3798 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003799 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003800 }
3801
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003802 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003803 SmallString<64> Str;
3804 llvm::raw_svector_ostream OS(Str);
3805 OS << *ClassTemplate;
3806 OS << "<";
3807 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3808 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3809 if (I)
3810 OS << ", ";
3811
3812 NamedDecl *Param = Params->getParam(I);
3813 if (Param->getIdentifier()) {
3814 OS << Param->getIdentifier()->getName();
3815 continue;
3816 }
3817
3818 // There is no parameter name, which makes this tricky. Try to come up
3819 // with something useful that isn't too long.
3820 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3821 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3822 else if (NonTypeTemplateParmDecl *NTTP
3823 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3824 OS << NTTP->getType().getAsString(Policy);
3825 else
3826 OS << "template<...> class";
3827 }
3828
3829 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003830 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003831 }
3832
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003833 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003834 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3835 // If the type was explicitly written, use that.
3836 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003837 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003838
Benjamin Kramer9170e912013-02-22 15:46:01 +00003839 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003840 llvm::raw_svector_ostream OS(Str);
3841 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003842 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003843 ClassSpec->getTemplateArgs().data(),
3844 ClassSpec->getTemplateArgs().size(),
3845 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003846 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003847 }
3848
3849 return clang_getCursorSpelling(C);
3850}
3851
3852CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3853 switch (Kind) {
3854 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003855 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003856 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003857 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003858 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003859 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003860 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003861 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003862 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003863 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003864 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003865 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003866 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003867 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003868 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003869 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003870 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003871 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003872 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003873 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003874 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003875 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003876 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003877 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003878 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003879 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003880 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003881 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003882 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003883 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003884 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003885 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003886 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003887 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003888 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003889 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003890 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003891 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003892 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003893 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003894 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003895 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003896 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003897 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003898 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003899 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003900 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003901 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003902 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003903 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003904 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003905 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003906 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003907 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003908 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003909 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003910 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003911 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003912 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003913 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003914 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003915 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003916 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003917 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003918 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003919 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003920 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003921 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003922 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003923 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003924 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003925 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003926 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003927 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003928 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003929 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003930 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003931 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003932 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003933 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003934 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003935 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003936 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003937 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003938 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003939 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003940 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003941 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003942 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003943 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003944 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003945 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003946 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003947 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003948 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003949 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003950 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003951 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003952 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003953 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003954 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003955 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003956 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003957 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003958 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003959 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003960 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003961 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003962 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003963 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003964 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003965 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003966 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003967 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003968 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003969 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003970 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003971 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003972 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003973 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003974 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003975 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003976 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003977 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003978 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003979 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003980 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003981 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003982 case CXCursor_ObjCSelfExpr:
3983 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003984 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003985 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003986 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003987 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003988 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003989 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003990 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003991 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003992 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003993 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003994 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003995 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003996 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003997 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003998 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003999 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004000 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004001 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004002 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004003 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004004 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004005 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004006 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004007 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004008 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004009 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004010 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004011 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004012 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004013 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004014 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004015 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004016 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004017 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004018 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004019 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004020 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004021 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004022 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004023 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004024 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004025 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004026 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004027 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004028 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004029 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004030 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004031 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004032 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004033 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004034 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004035 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004036 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004037 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004038 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004039 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004040 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004041 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004042 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004043 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004044 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004045 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004046 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004047 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004048 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004049 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004050 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004051 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004052 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004053 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004054 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004055 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004056 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004057 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004058 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004059 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004060 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004061 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004062 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004063 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004064 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004065 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004066 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004067 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004068 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004069 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004070 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004071 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00004072 case CXCursor_SEHLeaveStmt:
4073 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004074 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004075 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004076 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004077 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00004078 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004079 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00004080 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004081 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00004082 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004083 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00004084 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004085 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00004086 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004087 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004088 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004089 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004090 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004091 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004092 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004093 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004094 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004095 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004096 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004097 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004098 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004099 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004100 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004101 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004102 case CXCursor_PackedAttr:
4103 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00004104 case CXCursor_PureAttr:
4105 return cxstring::createRef("attribute(pure)");
4106 case CXCursor_ConstAttr:
4107 return cxstring::createRef("attribute(const)");
4108 case CXCursor_NoDuplicateAttr:
4109 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00004110 case CXCursor_CUDAConstantAttr:
4111 return cxstring::createRef("attribute(constant)");
4112 case CXCursor_CUDADeviceAttr:
4113 return cxstring::createRef("attribute(device)");
4114 case CXCursor_CUDAGlobalAttr:
4115 return cxstring::createRef("attribute(global)");
4116 case CXCursor_CUDAHostAttr:
4117 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00004118 case CXCursor_CUDASharedAttr:
4119 return cxstring::createRef("attribute(shared)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004120 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004121 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004122 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004123 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00004124 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004125 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004126 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004127 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004128 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004129 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00004130 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004131 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00004132 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004133 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004134 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004135 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004136 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004137 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004138 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004139 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004140 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004141 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004142 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004143 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004144 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004145 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004146 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004147 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004148 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004149 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004150 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004151 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004152 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004153 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004154 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004155 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004156 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004157 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004158 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004159 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004160 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004161 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004162 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004163 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004164 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004165 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004166 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004167 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004168 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004169 return cxstring::createRef("OMPParallelDirective");
4170 case CXCursor_OMPSimdDirective:
4171 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004172 case CXCursor_OMPForDirective:
4173 return cxstring::createRef("OMPForDirective");
Alexander Musmanf82886e2014-09-18 05:12:34 +00004174 case CXCursor_OMPForSimdDirective:
4175 return cxstring::createRef("OMPForSimdDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004176 case CXCursor_OMPSectionsDirective:
4177 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004178 case CXCursor_OMPSectionDirective:
4179 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004180 case CXCursor_OMPSingleDirective:
4181 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004182 case CXCursor_OMPMasterDirective:
4183 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004184 case CXCursor_OMPCriticalDirective:
4185 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004186 case CXCursor_OMPParallelForDirective:
4187 return cxstring::createRef("OMPParallelForDirective");
Alexander Musmane4e893b2014-09-23 09:33:00 +00004188 case CXCursor_OMPParallelForSimdDirective:
4189 return cxstring::createRef("OMPParallelForSimdDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004190 case CXCursor_OMPParallelSectionsDirective:
4191 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004192 case CXCursor_OMPTaskDirective:
4193 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004194 case CXCursor_OMPTaskyieldDirective:
4195 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004196 case CXCursor_OMPBarrierDirective:
4197 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004198 case CXCursor_OMPTaskwaitDirective:
4199 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00004200 case CXCursor_OMPFlushDirective:
4201 return cxstring::createRef("OMPFlushDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004202 case CXCursor_OMPOrderedDirective:
4203 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00004204 case CXCursor_OMPAtomicDirective:
4205 return cxstring::createRef("OMPAtomicDirective");
Alexey Bataev0bd520b2014-09-19 08:19:49 +00004206 case CXCursor_OMPTargetDirective:
4207 return cxstring::createRef("OMPTargetDirective");
Alexey Bataev13314bf2014-10-09 04:18:56 +00004208 case CXCursor_OMPTeamsDirective:
4209 return cxstring::createRef("OMPTeamsDirective");
Francisco Lopes da Silva975a9f62015-01-21 16:24:11 +00004210 case CXCursor_OverloadCandidate:
4211 return cxstring::createRef("OverloadCandidate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004212 }
4213
4214 llvm_unreachable("Unhandled CXCursorKind");
4215}
4216
4217struct GetCursorData {
4218 SourceLocation TokenBeginLoc;
4219 bool PointsAtMacroArgExpansion;
4220 bool VisitedObjCPropertyImplDecl;
4221 SourceLocation VisitedDeclaratorDeclStartLoc;
4222 CXCursor &BestCursor;
4223
4224 GetCursorData(SourceManager &SM,
4225 SourceLocation tokenBegin, CXCursor &outputCursor)
4226 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4227 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4228 VisitedObjCPropertyImplDecl = false;
4229 }
4230};
4231
4232static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4233 CXCursor parent,
4234 CXClientData client_data) {
4235 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4236 CXCursor *BestCursor = &Data->BestCursor;
4237
4238 // If we point inside a macro argument we should provide info of what the
4239 // token is so use the actual cursor, don't replace it with a macro expansion
4240 // cursor.
4241 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4242 return CXChildVisit_Recurse;
4243
4244 if (clang_isDeclaration(cursor.kind)) {
4245 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004246 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004247 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4248 if (MD->isImplicit())
4249 return CXChildVisit_Break;
4250
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004251 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004252 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4253 // Check that when we have multiple @class references in the same line,
4254 // that later ones do not override the previous ones.
4255 // If we have:
4256 // @class Foo, Bar;
4257 // source ranges for both start at '@', so 'Bar' will end up overriding
4258 // 'Foo' even though the cursor location was at 'Foo'.
4259 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4260 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004261 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004262 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4263 if (PrevID != ID &&
4264 !PrevID->isThisDeclarationADefinition() &&
4265 !ID->isThisDeclarationADefinition())
4266 return CXChildVisit_Break;
4267 }
4268
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004269 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004270 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4271 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4272 // Check that when we have multiple declarators in the same line,
4273 // that later ones do not override the previous ones.
4274 // If we have:
4275 // int Foo, Bar;
4276 // source ranges for both start at 'int', so 'Bar' will end up overriding
4277 // 'Foo' even though the cursor location was at 'Foo'.
4278 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4279 return CXChildVisit_Break;
4280 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4281
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004282 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004283 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4284 (void)PropImp;
4285 // Check that when we have multiple @synthesize in the same line,
4286 // that later ones do not override the previous ones.
4287 // If we have:
4288 // @synthesize Foo, Bar;
4289 // source ranges for both start at '@', so 'Bar' will end up overriding
4290 // 'Foo' even though the cursor location was at 'Foo'.
4291 if (Data->VisitedObjCPropertyImplDecl)
4292 return CXChildVisit_Break;
4293 Data->VisitedObjCPropertyImplDecl = true;
4294 }
4295 }
4296
4297 if (clang_isExpression(cursor.kind) &&
4298 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004299 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004300 // Avoid having the cursor of an expression replace the declaration cursor
4301 // when the expression source range overlaps the declaration range.
4302 // This can happen for C++ constructor expressions whose range generally
4303 // include the variable declaration, e.g.:
4304 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4305 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4306 D->getLocation() == Data->TokenBeginLoc)
4307 return CXChildVisit_Break;
4308 }
4309 }
4310
4311 // If our current best cursor is the construction of a temporary object,
4312 // don't replace that cursor with a type reference, because we want
4313 // clang_getCursor() to point at the constructor.
4314 if (clang_isExpression(BestCursor->kind) &&
4315 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4316 cursor.kind == CXCursor_TypeRef) {
4317 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4318 // as having the actual point on the type reference.
4319 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4320 return CXChildVisit_Recurse;
4321 }
4322
4323 *BestCursor = cursor;
4324 return CXChildVisit_Recurse;
4325}
4326
4327CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004328 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004329 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004330 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004331 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004332
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004333 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004334 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4335
4336 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4337 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4338
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004339 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004340 CXFile SearchFile;
4341 unsigned SearchLine, SearchColumn;
4342 CXFile ResultFile;
4343 unsigned ResultLine, ResultColumn;
4344 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4345 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4346 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004347
4348 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4349 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004350 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004351 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004352 SearchFileName = clang_getFileName(SearchFile);
4353 ResultFileName = clang_getFileName(ResultFile);
4354 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4355 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004356 *Log << llvm::format("(%s:%d:%d) = %s",
4357 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4358 clang_getCString(KindSpelling))
4359 << llvm::format("(%s:%d:%d):%s%s",
4360 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4361 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004362 clang_disposeString(SearchFileName);
4363 clang_disposeString(ResultFileName);
4364 clang_disposeString(KindSpelling);
4365 clang_disposeString(USR);
4366
4367 CXCursor Definition = clang_getCursorDefinition(Result);
4368 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4369 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4370 CXString DefinitionKindSpelling
4371 = clang_getCursorKindSpelling(Definition.kind);
4372 CXFile DefinitionFile;
4373 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004374 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004375 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004376 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004377 *Log << llvm::format(" -> %s(%s:%d:%d)",
4378 clang_getCString(DefinitionKindSpelling),
4379 clang_getCString(DefinitionFileName),
4380 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004381 clang_disposeString(DefinitionFileName);
4382 clang_disposeString(DefinitionKindSpelling);
4383 }
4384 }
4385
4386 return Result;
4387}
4388
4389CXCursor clang_getNullCursor(void) {
4390 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4391}
4392
4393unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004394 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4395 // can't set consistently. For example, when visiting a DeclStmt we will set
4396 // it but we don't set it on the result of clang_getCursorDefinition for
4397 // a reference of the same declaration.
4398 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4399 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4400 // to provide that kind of info.
4401 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004402 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004403 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004404 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004405
Guy Benyei11169dd2012-12-18 14:30:41 +00004406 return X == Y;
4407}
4408
4409unsigned clang_hashCursor(CXCursor C) {
4410 unsigned Index = 0;
4411 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4412 Index = 1;
4413
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004414 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004415 std::make_pair(C.kind, C.data[Index]));
4416}
4417
4418unsigned clang_isInvalid(enum CXCursorKind K) {
4419 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4420}
4421
4422unsigned clang_isDeclaration(enum CXCursorKind K) {
4423 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4424 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4425}
4426
4427unsigned clang_isReference(enum CXCursorKind K) {
4428 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4429}
4430
4431unsigned clang_isExpression(enum CXCursorKind K) {
4432 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4433}
4434
4435unsigned clang_isStatement(enum CXCursorKind K) {
4436 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4437}
4438
4439unsigned clang_isAttribute(enum CXCursorKind K) {
4440 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4441}
4442
4443unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4444 return K == CXCursor_TranslationUnit;
4445}
4446
4447unsigned clang_isPreprocessing(enum CXCursorKind K) {
4448 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4449}
4450
4451unsigned clang_isUnexposed(enum CXCursorKind K) {
4452 switch (K) {
4453 case CXCursor_UnexposedDecl:
4454 case CXCursor_UnexposedExpr:
4455 case CXCursor_UnexposedStmt:
4456 case CXCursor_UnexposedAttr:
4457 return true;
4458 default:
4459 return false;
4460 }
4461}
4462
4463CXCursorKind clang_getCursorKind(CXCursor C) {
4464 return C.kind;
4465}
4466
4467CXSourceLocation clang_getCursorLocation(CXCursor C) {
4468 if (clang_isReference(C.kind)) {
4469 switch (C.kind) {
4470 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004471 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004472 = getCursorObjCSuperClassRef(C);
4473 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4474 }
4475
4476 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004477 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004478 = getCursorObjCProtocolRef(C);
4479 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4480 }
4481
4482 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004483 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004484 = getCursorObjCClassRef(C);
4485 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4486 }
4487
4488 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004489 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004490 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4491 }
4492
4493 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004494 std::pair<const TemplateDecl *, SourceLocation> P =
4495 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004496 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4497 }
4498
4499 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004500 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004501 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4502 }
4503
4504 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004505 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004506 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4507 }
4508
4509 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004510 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004511 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4512 }
4513
4514 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004515 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004516 if (!BaseSpec)
4517 return clang_getNullLocation();
4518
4519 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4520 return cxloc::translateSourceLocation(getCursorContext(C),
4521 TSInfo->getTypeLoc().getBeginLoc());
4522
4523 return cxloc::translateSourceLocation(getCursorContext(C),
4524 BaseSpec->getLocStart());
4525 }
4526
4527 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004528 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004529 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4530 }
4531
4532 case CXCursor_OverloadedDeclRef:
4533 return cxloc::translateSourceLocation(getCursorContext(C),
4534 getCursorOverloadedDeclRef(C).second);
4535
4536 default:
4537 // FIXME: Need a way to enumerate all non-reference cases.
4538 llvm_unreachable("Missed a reference kind");
4539 }
4540 }
4541
4542 if (clang_isExpression(C.kind))
4543 return cxloc::translateSourceLocation(getCursorContext(C),
4544 getLocationFromExpr(getCursorExpr(C)));
4545
4546 if (clang_isStatement(C.kind))
4547 return cxloc::translateSourceLocation(getCursorContext(C),
4548 getCursorStmt(C)->getLocStart());
4549
4550 if (C.kind == CXCursor_PreprocessingDirective) {
4551 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4552 return cxloc::translateSourceLocation(getCursorContext(C), L);
4553 }
4554
4555 if (C.kind == CXCursor_MacroExpansion) {
4556 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004557 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004558 return cxloc::translateSourceLocation(getCursorContext(C), L);
4559 }
4560
4561 if (C.kind == CXCursor_MacroDefinition) {
4562 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4563 return cxloc::translateSourceLocation(getCursorContext(C), L);
4564 }
4565
4566 if (C.kind == CXCursor_InclusionDirective) {
4567 SourceLocation L
4568 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4569 return cxloc::translateSourceLocation(getCursorContext(C), L);
4570 }
4571
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004572 if (clang_isAttribute(C.kind)) {
4573 SourceLocation L
4574 = cxcursor::getCursorAttr(C)->getLocation();
4575 return cxloc::translateSourceLocation(getCursorContext(C), L);
4576 }
4577
Guy Benyei11169dd2012-12-18 14:30:41 +00004578 if (!clang_isDeclaration(C.kind))
4579 return clang_getNullLocation();
4580
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004581 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004582 if (!D)
4583 return clang_getNullLocation();
4584
4585 SourceLocation Loc = D->getLocation();
4586 // FIXME: Multiple variables declared in a single declaration
4587 // currently lack the information needed to correctly determine their
4588 // ranges when accounting for the type-specifier. We use context
4589 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4590 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004591 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004592 if (!cxcursor::isFirstInDeclGroup(C))
4593 Loc = VD->getLocation();
4594 }
4595
4596 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004597 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004598 Loc = MD->getSelectorStartLoc();
4599
4600 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4601}
4602
4603} // end extern "C"
4604
4605CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4606 assert(TU);
4607
4608 // Guard against an invalid SourceLocation, or we may assert in one
4609 // of the following calls.
4610 if (SLoc.isInvalid())
4611 return clang_getNullCursor();
4612
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004613 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004614
4615 // Translate the given source location to make it point at the beginning of
4616 // the token under the cursor.
4617 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4618 CXXUnit->getASTContext().getLangOpts());
4619
4620 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4621 if (SLoc.isValid()) {
4622 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4623 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4624 /*VisitPreprocessorLast=*/true,
4625 /*VisitIncludedEntities=*/false,
4626 SourceLocation(SLoc));
4627 CursorVis.visitFileRegion();
4628 }
4629
4630 return Result;
4631}
4632
4633static SourceRange getRawCursorExtent(CXCursor C) {
4634 if (clang_isReference(C.kind)) {
4635 switch (C.kind) {
4636 case CXCursor_ObjCSuperClassRef:
4637 return getCursorObjCSuperClassRef(C).second;
4638
4639 case CXCursor_ObjCProtocolRef:
4640 return getCursorObjCProtocolRef(C).second;
4641
4642 case CXCursor_ObjCClassRef:
4643 return getCursorObjCClassRef(C).second;
4644
4645 case CXCursor_TypeRef:
4646 return getCursorTypeRef(C).second;
4647
4648 case CXCursor_TemplateRef:
4649 return getCursorTemplateRef(C).second;
4650
4651 case CXCursor_NamespaceRef:
4652 return getCursorNamespaceRef(C).second;
4653
4654 case CXCursor_MemberRef:
4655 return getCursorMemberRef(C).second;
4656
4657 case CXCursor_CXXBaseSpecifier:
4658 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4659
4660 case CXCursor_LabelRef:
4661 return getCursorLabelRef(C).second;
4662
4663 case CXCursor_OverloadedDeclRef:
4664 return getCursorOverloadedDeclRef(C).second;
4665
4666 case CXCursor_VariableRef:
4667 return getCursorVariableRef(C).second;
4668
4669 default:
4670 // FIXME: Need a way to enumerate all non-reference cases.
4671 llvm_unreachable("Missed a reference kind");
4672 }
4673 }
4674
4675 if (clang_isExpression(C.kind))
4676 return getCursorExpr(C)->getSourceRange();
4677
4678 if (clang_isStatement(C.kind))
4679 return getCursorStmt(C)->getSourceRange();
4680
4681 if (clang_isAttribute(C.kind))
4682 return getCursorAttr(C)->getRange();
4683
4684 if (C.kind == CXCursor_PreprocessingDirective)
4685 return cxcursor::getCursorPreprocessingDirective(C);
4686
4687 if (C.kind == CXCursor_MacroExpansion) {
4688 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004689 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004690 return TU->mapRangeFromPreamble(Range);
4691 }
4692
4693 if (C.kind == CXCursor_MacroDefinition) {
4694 ASTUnit *TU = getCursorASTUnit(C);
4695 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4696 return TU->mapRangeFromPreamble(Range);
4697 }
4698
4699 if (C.kind == CXCursor_InclusionDirective) {
4700 ASTUnit *TU = getCursorASTUnit(C);
4701 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4702 return TU->mapRangeFromPreamble(Range);
4703 }
4704
4705 if (C.kind == CXCursor_TranslationUnit) {
4706 ASTUnit *TU = getCursorASTUnit(C);
4707 FileID MainID = TU->getSourceManager().getMainFileID();
4708 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4709 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4710 return SourceRange(Start, End);
4711 }
4712
4713 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004714 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004715 if (!D)
4716 return SourceRange();
4717
4718 SourceRange R = D->getSourceRange();
4719 // FIXME: Multiple variables declared in a single declaration
4720 // currently lack the information needed to correctly determine their
4721 // ranges when accounting for the type-specifier. We use context
4722 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4723 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004724 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004725 if (!cxcursor::isFirstInDeclGroup(C))
4726 R.setBegin(VD->getLocation());
4727 }
4728 return R;
4729 }
4730 return SourceRange();
4731}
4732
4733/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4734/// the decl-specifier-seq for declarations.
4735static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4736 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004737 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004738 if (!D)
4739 return SourceRange();
4740
4741 SourceRange R = D->getSourceRange();
4742
4743 // Adjust the start of the location for declarations preceded by
4744 // declaration specifiers.
4745 SourceLocation StartLoc;
4746 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4747 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4748 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004749 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004750 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4751 StartLoc = TI->getTypeLoc().getLocStart();
4752 }
4753
4754 if (StartLoc.isValid() && R.getBegin().isValid() &&
4755 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4756 R.setBegin(StartLoc);
4757
4758 // FIXME: Multiple variables declared in a single declaration
4759 // currently lack the information needed to correctly determine their
4760 // ranges when accounting for the type-specifier. We use context
4761 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4762 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004763 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004764 if (!cxcursor::isFirstInDeclGroup(C))
4765 R.setBegin(VD->getLocation());
4766 }
4767
4768 return R;
4769 }
4770
4771 return getRawCursorExtent(C);
4772}
4773
4774extern "C" {
4775
4776CXSourceRange clang_getCursorExtent(CXCursor C) {
4777 SourceRange R = getRawCursorExtent(C);
4778 if (R.isInvalid())
4779 return clang_getNullRange();
4780
4781 return cxloc::translateSourceRange(getCursorContext(C), R);
4782}
4783
4784CXCursor clang_getCursorReferenced(CXCursor C) {
4785 if (clang_isInvalid(C.kind))
4786 return clang_getNullCursor();
4787
4788 CXTranslationUnit tu = getCursorTU(C);
4789 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004790 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004791 if (!D)
4792 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004793 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004794 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004795 if (const ObjCPropertyImplDecl *PropImpl =
4796 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004797 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4798 return MakeCXCursor(Property, tu);
4799
4800 return C;
4801 }
4802
4803 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004804 const Expr *E = getCursorExpr(C);
4805 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004806 if (D) {
4807 CXCursor declCursor = MakeCXCursor(D, tu);
4808 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4809 declCursor);
4810 return declCursor;
4811 }
4812
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004813 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004814 return MakeCursorOverloadedDeclRef(Ovl, tu);
4815
4816 return clang_getNullCursor();
4817 }
4818
4819 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004820 const Stmt *S = getCursorStmt(C);
4821 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004822 if (LabelDecl *label = Goto->getLabel())
4823 if (LabelStmt *labelS = label->getStmt())
4824 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4825
4826 return clang_getNullCursor();
4827 }
4828
4829 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004830 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004831 return MakeMacroDefinitionCursor(Def, tu);
4832 }
4833
4834 if (!clang_isReference(C.kind))
4835 return clang_getNullCursor();
4836
4837 switch (C.kind) {
4838 case CXCursor_ObjCSuperClassRef:
4839 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4840
4841 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004842 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4843 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004844 return MakeCXCursor(Def, tu);
4845
4846 return MakeCXCursor(Prot, tu);
4847 }
4848
4849 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004850 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4851 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004852 return MakeCXCursor(Def, tu);
4853
4854 return MakeCXCursor(Class, tu);
4855 }
4856
4857 case CXCursor_TypeRef:
4858 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4859
4860 case CXCursor_TemplateRef:
4861 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4862
4863 case CXCursor_NamespaceRef:
4864 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4865
4866 case CXCursor_MemberRef:
4867 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4868
4869 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004870 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004871 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4872 tu ));
4873 }
4874
4875 case CXCursor_LabelRef:
4876 // FIXME: We end up faking the "parent" declaration here because we
4877 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004878 return MakeCXCursor(getCursorLabelRef(C).first,
4879 cxtu::getASTUnit(tu)->getASTContext()
4880 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004881 tu);
4882
4883 case CXCursor_OverloadedDeclRef:
4884 return C;
4885
4886 case CXCursor_VariableRef:
4887 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4888
4889 default:
4890 // We would prefer to enumerate all non-reference cursor kinds here.
4891 llvm_unreachable("Unhandled reference cursor kind");
4892 }
4893}
4894
4895CXCursor clang_getCursorDefinition(CXCursor C) {
4896 if (clang_isInvalid(C.kind))
4897 return clang_getNullCursor();
4898
4899 CXTranslationUnit TU = getCursorTU(C);
4900
4901 bool WasReference = false;
4902 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4903 C = clang_getCursorReferenced(C);
4904 WasReference = true;
4905 }
4906
4907 if (C.kind == CXCursor_MacroExpansion)
4908 return clang_getCursorReferenced(C);
4909
4910 if (!clang_isDeclaration(C.kind))
4911 return clang_getNullCursor();
4912
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004913 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004914 if (!D)
4915 return clang_getNullCursor();
4916
4917 switch (D->getKind()) {
4918 // Declaration kinds that don't really separate the notions of
4919 // declaration and definition.
4920 case Decl::Namespace:
4921 case Decl::Typedef:
4922 case Decl::TypeAlias:
4923 case Decl::TypeAliasTemplate:
4924 case Decl::TemplateTypeParm:
4925 case Decl::EnumConstant:
4926 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004927 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004928 case Decl::IndirectField:
4929 case Decl::ObjCIvar:
4930 case Decl::ObjCAtDefsField:
4931 case Decl::ImplicitParam:
4932 case Decl::ParmVar:
4933 case Decl::NonTypeTemplateParm:
4934 case Decl::TemplateTemplateParm:
4935 case Decl::ObjCCategoryImpl:
4936 case Decl::ObjCImplementation:
4937 case Decl::AccessSpec:
4938 case Decl::LinkageSpec:
4939 case Decl::ObjCPropertyImpl:
4940 case Decl::FileScopeAsm:
4941 case Decl::StaticAssert:
4942 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004943 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004944 case Decl::Label: // FIXME: Is this right??
4945 case Decl::ClassScopeFunctionSpecialization:
4946 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004947 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004948 return C;
4949
4950 // Declaration kinds that don't make any sense here, but are
4951 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004952 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004953 case Decl::TranslationUnit:
4954 break;
4955
4956 // Declaration kinds for which the definition is not resolvable.
4957 case Decl::UnresolvedUsingTypename:
4958 case Decl::UnresolvedUsingValue:
4959 break;
4960
4961 case Decl::UsingDirective:
4962 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4963 TU);
4964
4965 case Decl::NamespaceAlias:
4966 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4967
4968 case Decl::Enum:
4969 case Decl::Record:
4970 case Decl::CXXRecord:
4971 case Decl::ClassTemplateSpecialization:
4972 case Decl::ClassTemplatePartialSpecialization:
4973 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4974 return MakeCXCursor(Def, TU);
4975 return clang_getNullCursor();
4976
4977 case Decl::Function:
4978 case Decl::CXXMethod:
4979 case Decl::CXXConstructor:
4980 case Decl::CXXDestructor:
4981 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00004982 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004983 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004984 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004985 return clang_getNullCursor();
4986 }
4987
Larisse Voufo39a1e502013-08-06 01:03:05 +00004988 case Decl::Var:
4989 case Decl::VarTemplateSpecialization:
4990 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004991 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004992 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004993 return MakeCXCursor(Def, TU);
4994 return clang_getNullCursor();
4995 }
4996
4997 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00004998 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004999 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
5000 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
5001 return clang_getNullCursor();
5002 }
5003
5004 case Decl::ClassTemplate: {
5005 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
5006 ->getDefinition())
5007 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
5008 TU);
5009 return clang_getNullCursor();
5010 }
5011
Larisse Voufo39a1e502013-08-06 01:03:05 +00005012 case Decl::VarTemplate: {
5013 if (VarDecl *Def =
5014 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
5015 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
5016 return clang_getNullCursor();
5017 }
5018
Guy Benyei11169dd2012-12-18 14:30:41 +00005019 case Decl::Using:
5020 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
5021 D->getLocation(), TU);
5022
5023 case Decl::UsingShadow:
5024 return clang_getCursorDefinition(
5025 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
5026 TU));
5027
5028 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005029 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005030 if (Method->isThisDeclarationADefinition())
5031 return C;
5032
5033 // Dig out the method definition in the associated
5034 // @implementation, if we have it.
5035 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005036 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005037 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
5038 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
5039 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
5040 Method->isInstanceMethod()))
5041 if (Def->isThisDeclarationADefinition())
5042 return MakeCXCursor(Def, TU);
5043
5044 return clang_getNullCursor();
5045 }
5046
5047 case Decl::ObjCCategory:
5048 if (ObjCCategoryImplDecl *Impl
5049 = cast<ObjCCategoryDecl>(D)->getImplementation())
5050 return MakeCXCursor(Impl, TU);
5051 return clang_getNullCursor();
5052
5053 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005054 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005055 return MakeCXCursor(Def, TU);
5056 return clang_getNullCursor();
5057
5058 case Decl::ObjCInterface: {
5059 // There are two notions of a "definition" for an Objective-C
5060 // class: the interface and its implementation. When we resolved a
5061 // reference to an Objective-C class, produce the @interface as
5062 // the definition; when we were provided with the interface,
5063 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005064 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005065 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005066 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005067 return MakeCXCursor(Def, TU);
5068 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
5069 return MakeCXCursor(Impl, TU);
5070 return clang_getNullCursor();
5071 }
5072
5073 case Decl::ObjCProperty:
5074 // FIXME: We don't really know where to find the
5075 // ObjCPropertyImplDecls that implement this property.
5076 return clang_getNullCursor();
5077
5078 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005079 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005080 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005081 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005082 return MakeCXCursor(Def, TU);
5083
5084 return clang_getNullCursor();
5085
5086 case Decl::Friend:
5087 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
5088 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5089 return clang_getNullCursor();
5090
5091 case Decl::FriendTemplate:
5092 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
5093 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5094 return clang_getNullCursor();
5095 }
5096
5097 return clang_getNullCursor();
5098}
5099
5100unsigned clang_isCursorDefinition(CXCursor C) {
5101 if (!clang_isDeclaration(C.kind))
5102 return 0;
5103
5104 return clang_getCursorDefinition(C) == C;
5105}
5106
5107CXCursor clang_getCanonicalCursor(CXCursor C) {
5108 if (!clang_isDeclaration(C.kind))
5109 return C;
5110
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005111 if (const Decl *D = getCursorDecl(C)) {
5112 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005113 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5114 return MakeCXCursor(CatD, getCursorTU(C));
5115
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005116 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5117 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00005118 return MakeCXCursor(IFD, getCursorTU(C));
5119
5120 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5121 }
5122
5123 return C;
5124}
5125
5126int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5127 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5128}
5129
5130unsigned clang_getNumOverloadedDecls(CXCursor C) {
5131 if (C.kind != CXCursor_OverloadedDeclRef)
5132 return 0;
5133
5134 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005135 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005136 return E->getNumDecls();
5137
5138 if (OverloadedTemplateStorage *S
5139 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5140 return S->size();
5141
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005142 const Decl *D = Storage.get<const Decl *>();
5143 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005144 return Using->shadow_size();
5145
5146 return 0;
5147}
5148
5149CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5150 if (cursor.kind != CXCursor_OverloadedDeclRef)
5151 return clang_getNullCursor();
5152
5153 if (index >= clang_getNumOverloadedDecls(cursor))
5154 return clang_getNullCursor();
5155
5156 CXTranslationUnit TU = getCursorTU(cursor);
5157 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005158 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005159 return MakeCXCursor(E->decls_begin()[index], TU);
5160
5161 if (OverloadedTemplateStorage *S
5162 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5163 return MakeCXCursor(S->begin()[index], TU);
5164
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005165 const Decl *D = Storage.get<const Decl *>();
5166 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005167 // FIXME: This is, unfortunately, linear time.
5168 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5169 std::advance(Pos, index);
5170 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5171 }
5172
5173 return clang_getNullCursor();
5174}
5175
5176void clang_getDefinitionSpellingAndExtent(CXCursor C,
5177 const char **startBuf,
5178 const char **endBuf,
5179 unsigned *startLine,
5180 unsigned *startColumn,
5181 unsigned *endLine,
5182 unsigned *endColumn) {
5183 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005184 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005185 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5186
5187 SourceManager &SM = FD->getASTContext().getSourceManager();
5188 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5189 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5190 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5191 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5192 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5193 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5194}
5195
5196
5197CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5198 unsigned PieceIndex) {
5199 RefNamePieces Pieces;
5200
5201 switch (C.kind) {
5202 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005203 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005204 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5205 E->getQualifierLoc().getSourceRange());
5206 break;
5207
5208 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005209 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005210 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
5211 E->getQualifierLoc().getSourceRange(),
5212 E->getOptionalExplicitTemplateArgs());
5213 break;
5214
5215 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005216 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005217 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005218 const Expr *Callee = OCE->getCallee();
5219 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005220 Callee = ICE->getSubExpr();
5221
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005222 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005223 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5224 DRE->getQualifierLoc().getSourceRange());
5225 }
5226 break;
5227
5228 default:
5229 break;
5230 }
5231
5232 if (Pieces.empty()) {
5233 if (PieceIndex == 0)
5234 return clang_getCursorExtent(C);
5235 } else if (PieceIndex < Pieces.size()) {
5236 SourceRange R = Pieces[PieceIndex];
5237 if (R.isValid())
5238 return cxloc::translateSourceRange(getCursorContext(C), R);
5239 }
5240
5241 return clang_getNullRange();
5242}
5243
5244void clang_enableStackTraces(void) {
5245 llvm::sys::PrintStackTraceOnErrorSignal();
5246}
5247
5248void clang_executeOnThread(void (*fn)(void*), void *user_data,
5249 unsigned stack_size) {
5250 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5251}
5252
5253} // end: extern "C"
5254
5255//===----------------------------------------------------------------------===//
5256// Token-based Operations.
5257//===----------------------------------------------------------------------===//
5258
5259/* CXToken layout:
5260 * int_data[0]: a CXTokenKind
5261 * int_data[1]: starting token location
5262 * int_data[2]: token length
5263 * int_data[3]: reserved
5264 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5265 * otherwise unused.
5266 */
5267extern "C" {
5268
5269CXTokenKind clang_getTokenKind(CXToken CXTok) {
5270 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5271}
5272
5273CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5274 switch (clang_getTokenKind(CXTok)) {
5275 case CXToken_Identifier:
5276 case CXToken_Keyword:
5277 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005278 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005279 ->getNameStart());
5280
5281 case CXToken_Literal: {
5282 // We have stashed the starting pointer in the ptr_data field. Use it.
5283 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005284 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005285 }
5286
5287 case CXToken_Punctuation:
5288 case CXToken_Comment:
5289 break;
5290 }
5291
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005292 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005293 LOG_BAD_TU(TU);
5294 return cxstring::createEmpty();
5295 }
5296
Guy Benyei11169dd2012-12-18 14:30:41 +00005297 // We have to find the starting buffer pointer the hard way, by
5298 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005299 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005300 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005301 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005302
5303 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5304 std::pair<FileID, unsigned> LocInfo
5305 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5306 bool Invalid = false;
5307 StringRef Buffer
5308 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5309 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005310 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005311
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005312 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005313}
5314
5315CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005316 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005317 LOG_BAD_TU(TU);
5318 return clang_getNullLocation();
5319 }
5320
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005321 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005322 if (!CXXUnit)
5323 return clang_getNullLocation();
5324
5325 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5326 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5327}
5328
5329CXSourceRange clang_getTokenExtent(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_getNullRange();
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_getNullRange();
5338
5339 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5340 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5341}
5342
5343static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5344 SmallVectorImpl<CXToken> &CXTokens) {
5345 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5346 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005347 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005348 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005349 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005350
5351 // Cannot tokenize across files.
5352 if (BeginLocInfo.first != EndLocInfo.first)
5353 return;
5354
5355 // Create a lexer
5356 bool Invalid = false;
5357 StringRef Buffer
5358 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5359 if (Invalid)
5360 return;
5361
5362 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5363 CXXUnit->getASTContext().getLangOpts(),
5364 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5365 Lex.SetCommentRetentionState(true);
5366
5367 // Lex tokens until we hit the end of the range.
5368 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5369 Token Tok;
5370 bool previousWasAt = false;
5371 do {
5372 // Lex the next token
5373 Lex.LexFromRawLexer(Tok);
5374 if (Tok.is(tok::eof))
5375 break;
5376
5377 // Initialize the CXToken.
5378 CXToken CXTok;
5379
5380 // - Common fields
5381 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5382 CXTok.int_data[2] = Tok.getLength();
5383 CXTok.int_data[3] = 0;
5384
5385 // - Kind-specific fields
5386 if (Tok.isLiteral()) {
5387 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005388 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005389 } else if (Tok.is(tok::raw_identifier)) {
5390 // Lookup the identifier to determine whether we have a keyword.
5391 IdentifierInfo *II
5392 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5393
5394 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5395 CXTok.int_data[0] = CXToken_Keyword;
5396 }
5397 else {
5398 CXTok.int_data[0] = Tok.is(tok::identifier)
5399 ? CXToken_Identifier
5400 : CXToken_Keyword;
5401 }
5402 CXTok.ptr_data = II;
5403 } else if (Tok.is(tok::comment)) {
5404 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005405 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005406 } else {
5407 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005408 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005409 }
5410 CXTokens.push_back(CXTok);
5411 previousWasAt = Tok.is(tok::at);
5412 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5413}
5414
5415void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5416 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005417 LOG_FUNC_SECTION {
5418 *Log << TU << ' ' << Range;
5419 }
5420
Guy Benyei11169dd2012-12-18 14:30:41 +00005421 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005422 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005423 if (NumTokens)
5424 *NumTokens = 0;
5425
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005426 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005427 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005428 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005429 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005430
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005431 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005432 if (!CXXUnit || !Tokens || !NumTokens)
5433 return;
5434
5435 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5436
5437 SourceRange R = cxloc::translateCXSourceRange(Range);
5438 if (R.isInvalid())
5439 return;
5440
5441 SmallVector<CXToken, 32> CXTokens;
5442 getTokens(CXXUnit, R, CXTokens);
5443
5444 if (CXTokens.empty())
5445 return;
5446
5447 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5448 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5449 *NumTokens = CXTokens.size();
5450}
5451
5452void clang_disposeTokens(CXTranslationUnit TU,
5453 CXToken *Tokens, unsigned NumTokens) {
5454 free(Tokens);
5455}
5456
5457} // end: extern "C"
5458
5459//===----------------------------------------------------------------------===//
5460// Token annotation APIs.
5461//===----------------------------------------------------------------------===//
5462
Guy Benyei11169dd2012-12-18 14:30:41 +00005463static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5464 CXCursor parent,
5465 CXClientData client_data);
5466static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5467 CXClientData client_data);
5468
5469namespace {
5470class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005471 CXToken *Tokens;
5472 CXCursor *Cursors;
5473 unsigned NumTokens;
5474 unsigned TokIdx;
5475 unsigned PreprocessingTokIdx;
5476 CursorVisitor AnnotateVis;
5477 SourceManager &SrcMgr;
5478 bool HasContextSensitiveKeywords;
5479
5480 struct PostChildrenInfo {
5481 CXCursor Cursor;
5482 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005483 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005484 unsigned BeforeChildrenTokenIdx;
5485 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005486 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005487
5488 CXToken &getTok(unsigned Idx) {
5489 assert(Idx < NumTokens);
5490 return Tokens[Idx];
5491 }
5492 const CXToken &getTok(unsigned Idx) const {
5493 assert(Idx < NumTokens);
5494 return Tokens[Idx];
5495 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005496 bool MoreTokens() const { return TokIdx < NumTokens; }
5497 unsigned NextToken() const { return TokIdx; }
5498 void AdvanceToken() { ++TokIdx; }
5499 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005500 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005501 }
5502 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005503 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005504 }
5505 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005506 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005507 }
5508
5509 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005510 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005511 SourceRange);
5512
5513public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005514 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005515 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005516 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005517 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005518 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005519 AnnotateTokensVisitor, this,
5520 /*VisitPreprocessorLast=*/true,
5521 /*VisitIncludedEntities=*/false,
5522 RegionOfInterest,
5523 /*VisitDeclsOnly=*/false,
5524 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005525 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005526 HasContextSensitiveKeywords(false) { }
5527
5528 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5529 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5530 bool postVisitChildren(CXCursor cursor);
5531 void AnnotateTokens();
5532
5533 /// \brief Determine whether the annotator saw any cursors that have
5534 /// context-sensitive keywords.
5535 bool hasContextSensitiveKeywords() const {
5536 return HasContextSensitiveKeywords;
5537 }
5538
5539 ~AnnotateTokensWorker() {
5540 assert(PostChildrenInfos.empty());
5541 }
5542};
5543}
5544
5545void AnnotateTokensWorker::AnnotateTokens() {
5546 // Walk the AST within the region of interest, annotating tokens
5547 // along the way.
5548 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005549}
Guy Benyei11169dd2012-12-18 14:30:41 +00005550
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005551static inline void updateCursorAnnotation(CXCursor &Cursor,
5552 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005553 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005554 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005555 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005556}
5557
5558/// \brief It annotates and advances tokens with a cursor until the comparison
5559//// between the cursor location and the source range is the same as
5560/// \arg compResult.
5561///
5562/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5563/// Pass RangeOverlap to annotate tokens inside a range.
5564void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5565 RangeComparisonResult compResult,
5566 SourceRange range) {
5567 while (MoreTokens()) {
5568 const unsigned I = NextToken();
5569 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005570 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5571 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005572
5573 SourceLocation TokLoc = GetTokenLoc(I);
5574 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005575 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005576 AdvanceToken();
5577 continue;
5578 }
5579 break;
5580 }
5581}
5582
5583/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005584/// \returns true if it advanced beyond all macro tokens, false otherwise.
5585bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005586 CXCursor updateC,
5587 RangeComparisonResult compResult,
5588 SourceRange range) {
5589 assert(MoreTokens());
5590 assert(isFunctionMacroToken(NextToken()) &&
5591 "Should be called only for macro arg tokens");
5592
5593 // This works differently than annotateAndAdvanceTokens; because expanded
5594 // macro arguments can have arbitrary translation-unit source order, we do not
5595 // advance the token index one by one until a token fails the range test.
5596 // We only advance once past all of the macro arg tokens if all of them
5597 // pass the range test. If one of them fails we keep the token index pointing
5598 // at the start of the macro arg tokens so that the failing token will be
5599 // annotated by a subsequent annotation try.
5600
5601 bool atLeastOneCompFail = false;
5602
5603 unsigned I = NextToken();
5604 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5605 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5606 if (TokLoc.isFileID())
5607 continue; // not macro arg token, it's parens or comma.
5608 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5609 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5610 Cursors[I] = updateC;
5611 } else
5612 atLeastOneCompFail = true;
5613 }
5614
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005615 if (atLeastOneCompFail)
5616 return false;
5617
5618 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5619 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005620}
5621
5622enum CXChildVisitResult
5623AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005624 SourceRange cursorRange = getRawCursorExtent(cursor);
5625 if (cursorRange.isInvalid())
5626 return CXChildVisit_Recurse;
5627
5628 if (!HasContextSensitiveKeywords) {
5629 // Objective-C properties can have context-sensitive keywords.
5630 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005631 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005632 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5633 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5634 }
5635 // Objective-C methods can have context-sensitive keywords.
5636 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5637 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005638 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005639 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5640 if (Method->getObjCDeclQualifier())
5641 HasContextSensitiveKeywords = true;
5642 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005643 for (const auto *P : Method->params()) {
5644 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005645 HasContextSensitiveKeywords = true;
5646 break;
5647 }
5648 }
5649 }
5650 }
5651 }
5652 // C++ methods can have context-sensitive keywords.
5653 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005654 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005655 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5656 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5657 HasContextSensitiveKeywords = true;
5658 }
5659 }
5660 // C++ classes can have context-sensitive keywords.
5661 else if (cursor.kind == CXCursor_StructDecl ||
5662 cursor.kind == CXCursor_ClassDecl ||
5663 cursor.kind == CXCursor_ClassTemplate ||
5664 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005665 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005666 if (D->hasAttr<FinalAttr>())
5667 HasContextSensitiveKeywords = true;
5668 }
5669 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005670
5671 // Don't override a property annotation with its getter/setter method.
5672 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5673 parent.kind == CXCursor_ObjCPropertyDecl)
5674 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005675
5676 if (clang_isPreprocessing(cursor.kind)) {
5677 // Items in the preprocessing record are kept separate from items in
5678 // declarations, so we keep a separate token index.
5679 unsigned SavedTokIdx = TokIdx;
5680 TokIdx = PreprocessingTokIdx;
5681
5682 // Skip tokens up until we catch up to the beginning of the preprocessing
5683 // entry.
5684 while (MoreTokens()) {
5685 const unsigned I = NextToken();
5686 SourceLocation TokLoc = GetTokenLoc(I);
5687 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5688 case RangeBefore:
5689 AdvanceToken();
5690 continue;
5691 case RangeAfter:
5692 case RangeOverlap:
5693 break;
5694 }
5695 break;
5696 }
5697
5698 // Look at all of the tokens within this range.
5699 while (MoreTokens()) {
5700 const unsigned I = NextToken();
5701 SourceLocation TokLoc = GetTokenLoc(I);
5702 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5703 case RangeBefore:
5704 llvm_unreachable("Infeasible");
5705 case RangeAfter:
5706 break;
5707 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005708 // For macro expansions, just note where the beginning of the macro
5709 // expansion occurs.
5710 if (cursor.kind == CXCursor_MacroExpansion) {
5711 if (TokLoc == cursorRange.getBegin())
5712 Cursors[I] = cursor;
5713 AdvanceToken();
5714 break;
5715 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005716 // We may have already annotated macro names inside macro definitions.
5717 if (Cursors[I].kind != CXCursor_MacroExpansion)
5718 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005719 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005720 continue;
5721 }
5722 break;
5723 }
5724
5725 // Save the preprocessing token index; restore the non-preprocessing
5726 // token index.
5727 PreprocessingTokIdx = TokIdx;
5728 TokIdx = SavedTokIdx;
5729 return CXChildVisit_Recurse;
5730 }
5731
5732 if (cursorRange.isInvalid())
5733 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005734
5735 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005736 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005737 const enum CXCursorKind K = clang_getCursorKind(parent);
5738 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005739 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5740 // Attributes are annotated out-of-order, skip tokens until we reach it.
5741 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005742 ? clang_getNullCursor() : parent;
5743
5744 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5745
5746 // Avoid having the cursor of an expression "overwrite" the annotation of the
5747 // variable declaration that it belongs to.
5748 // This can happen for C++ constructor expressions whose range generally
5749 // include the variable declaration, e.g.:
5750 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005751 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005752 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005753 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005754 const unsigned I = NextToken();
5755 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5756 E->getLocStart() == D->getLocation() &&
5757 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005758 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005759 AdvanceToken();
5760 }
5761 }
5762 }
5763
5764 // Before recursing into the children keep some state that we are going
5765 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5766 // extra work after the child nodes are visited.
5767 // Note that we don't call VisitChildren here to avoid traversing statements
5768 // code-recursively which can blow the stack.
5769
5770 PostChildrenInfo Info;
5771 Info.Cursor = cursor;
5772 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005773 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005774 Info.BeforeChildrenTokenIdx = NextToken();
5775 PostChildrenInfos.push_back(Info);
5776
5777 return CXChildVisit_Recurse;
5778}
5779
5780bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5781 if (PostChildrenInfos.empty())
5782 return false;
5783 const PostChildrenInfo &Info = PostChildrenInfos.back();
5784 if (!clang_equalCursors(Info.Cursor, cursor))
5785 return false;
5786
5787 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5788 const unsigned AfterChildren = NextToken();
5789 SourceRange cursorRange = Info.CursorRange;
5790
5791 // Scan the tokens that are at the end of the cursor, but are not captured
5792 // but the child cursors.
5793 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5794
5795 // Scan the tokens that are at the beginning of the cursor, but are not
5796 // capture by the child cursors.
5797 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5798 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5799 break;
5800
5801 Cursors[I] = cursor;
5802 }
5803
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005804 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5805 // encountered the attribute cursor.
5806 if (clang_isAttribute(cursor.kind))
5807 TokIdx = Info.BeforeReachingCursorIdx;
5808
Guy Benyei11169dd2012-12-18 14:30:41 +00005809 PostChildrenInfos.pop_back();
5810 return false;
5811}
5812
5813static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5814 CXCursor parent,
5815 CXClientData client_data) {
5816 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5817}
5818
5819static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5820 CXClientData client_data) {
5821 return static_cast<AnnotateTokensWorker*>(client_data)->
5822 postVisitChildren(cursor);
5823}
5824
5825namespace {
5826
5827/// \brief Uses the macro expansions in the preprocessing record to find
5828/// and mark tokens that are macro arguments. This info is used by the
5829/// AnnotateTokensWorker.
5830class MarkMacroArgTokensVisitor {
5831 SourceManager &SM;
5832 CXToken *Tokens;
5833 unsigned NumTokens;
5834 unsigned CurIdx;
5835
5836public:
5837 MarkMacroArgTokensVisitor(SourceManager &SM,
5838 CXToken *tokens, unsigned numTokens)
5839 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5840
5841 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5842 if (cursor.kind != CXCursor_MacroExpansion)
5843 return CXChildVisit_Continue;
5844
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005845 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005846 if (macroRange.getBegin() == macroRange.getEnd())
5847 return CXChildVisit_Continue; // it's not a function macro.
5848
5849 for (; CurIdx < NumTokens; ++CurIdx) {
5850 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5851 macroRange.getBegin()))
5852 break;
5853 }
5854
5855 if (CurIdx == NumTokens)
5856 return CXChildVisit_Break;
5857
5858 for (; CurIdx < NumTokens; ++CurIdx) {
5859 SourceLocation tokLoc = getTokenLoc(CurIdx);
5860 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5861 break;
5862
5863 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5864 }
5865
5866 if (CurIdx == NumTokens)
5867 return CXChildVisit_Break;
5868
5869 return CXChildVisit_Continue;
5870 }
5871
5872private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005873 CXToken &getTok(unsigned Idx) {
5874 assert(Idx < NumTokens);
5875 return Tokens[Idx];
5876 }
5877 const CXToken &getTok(unsigned Idx) const {
5878 assert(Idx < NumTokens);
5879 return Tokens[Idx];
5880 }
5881
Guy Benyei11169dd2012-12-18 14:30:41 +00005882 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005883 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005884 }
5885
5886 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5887 // The third field is reserved and currently not used. Use it here
5888 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005889 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005890 }
5891};
5892
5893} // end anonymous namespace
5894
5895static CXChildVisitResult
5896MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5897 CXClientData client_data) {
5898 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5899 parent);
5900}
5901
5902namespace {
5903 struct clang_annotateTokens_Data {
5904 CXTranslationUnit TU;
5905 ASTUnit *CXXUnit;
5906 CXToken *Tokens;
5907 unsigned NumTokens;
5908 CXCursor *Cursors;
5909 };
5910}
5911
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005912/// \brief Used by \c annotatePreprocessorTokens.
5913/// \returns true if lexing was finished, false otherwise.
5914static bool lexNext(Lexer &Lex, Token &Tok,
5915 unsigned &NextIdx, unsigned NumTokens) {
5916 if (NextIdx >= NumTokens)
5917 return true;
5918
5919 ++NextIdx;
5920 Lex.LexFromRawLexer(Tok);
5921 if (Tok.is(tok::eof))
5922 return true;
5923
5924 return false;
5925}
5926
Guy Benyei11169dd2012-12-18 14:30:41 +00005927static void annotatePreprocessorTokens(CXTranslationUnit TU,
5928 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005929 CXCursor *Cursors,
5930 CXToken *Tokens,
5931 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005932 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005933
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005934 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005935 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5936 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005937 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005938 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005939 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005940
5941 if (BeginLocInfo.first != EndLocInfo.first)
5942 return;
5943
5944 StringRef Buffer;
5945 bool Invalid = false;
5946 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5947 if (Buffer.empty() || Invalid)
5948 return;
5949
5950 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5951 CXXUnit->getASTContext().getLangOpts(),
5952 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5953 Buffer.end());
5954 Lex.SetCommentRetentionState(true);
5955
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005956 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005957 // Lex tokens in raw mode until we hit the end of the range, to avoid
5958 // entering #includes or expanding macros.
5959 while (true) {
5960 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005961 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5962 break;
5963 unsigned TokIdx = NextIdx-1;
5964 assert(Tok.getLocation() ==
5965 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005966
5967 reprocess:
5968 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005969 // We have found a preprocessing directive. Annotate the tokens
5970 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005971 //
5972 // FIXME: Some simple tests here could identify macro definitions and
5973 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005974
5975 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005976 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5977 break;
5978
Craig Topper69186e72014-06-08 08:38:04 +00005979 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00005980 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005981 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5982 break;
5983
5984 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00005985 IdentifierInfo &II =
5986 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005987 SourceLocation MappedTokLoc =
5988 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5989 MI = getMacroInfo(II, MappedTokLoc, TU);
5990 }
5991 }
5992
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005993 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005994 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005995 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5996 finished = true;
5997 break;
5998 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005999 // If we are in a macro definition, check if the token was ever a
6000 // macro name and annotate it if that's the case.
6001 if (MI) {
6002 SourceLocation SaveLoc = Tok.getLocation();
6003 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
6004 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
6005 Tok.setLocation(SaveLoc);
6006 if (MacroDef)
6007 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
6008 Tok.getLocation(), TU);
6009 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006010 } while (!Tok.isAtStartOfLine());
6011
6012 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
6013 assert(TokIdx <= LastIdx);
6014 SourceLocation EndLoc =
6015 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
6016 CXCursor Cursor =
6017 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
6018
6019 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006020 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006021
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006022 if (finished)
6023 break;
6024 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00006025 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006026 }
6027}
6028
6029// This gets run a separate thread to avoid stack blowout.
6030static void clang_annotateTokensImpl(void *UserData) {
6031 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
6032 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
6033 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
6034 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
6035 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
6036
Dmitri Gribenko183436e2013-01-26 21:49:50 +00006037 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006038 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
6039 setThreadBackgroundPriority();
6040
6041 // Determine the region of interest, which contains all of the tokens.
6042 SourceRange RegionOfInterest;
6043 RegionOfInterest.setBegin(
6044 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
6045 RegionOfInterest.setEnd(
6046 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
6047 Tokens[NumTokens-1])));
6048
Guy Benyei11169dd2012-12-18 14:30:41 +00006049 // Relex the tokens within the source range to look for preprocessing
6050 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006051 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006052
6053 // If begin location points inside a macro argument, set it to the expansion
6054 // location so we can have the full context when annotating semantically.
6055 {
6056 SourceManager &SM = CXXUnit->getSourceManager();
6057 SourceLocation Loc =
6058 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
6059 if (Loc.isMacroID())
6060 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
6061 }
6062
Guy Benyei11169dd2012-12-18 14:30:41 +00006063 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
6064 // Search and mark tokens that are macro argument expansions.
6065 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
6066 Tokens, NumTokens);
6067 CursorVisitor MacroArgMarker(TU,
6068 MarkMacroArgTokensVisitorDelegate, &Visitor,
6069 /*VisitPreprocessorLast=*/true,
6070 /*VisitIncludedEntities=*/false,
6071 RegionOfInterest);
6072 MacroArgMarker.visitPreprocessedEntitiesInRegion();
6073 }
6074
6075 // Annotate all of the source locations in the region of interest that map to
6076 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006077 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00006078
6079 // FIXME: We use a ridiculous stack size here because the data-recursion
6080 // algorithm uses a large stack frame than the non-data recursive version,
6081 // and AnnotationTokensWorker currently transforms the data-recursion
6082 // algorithm back into a traditional recursion by explicitly calling
6083 // VisitChildren(). We will need to remove this explicit recursive call.
6084 W.AnnotateTokens();
6085
6086 // If we ran into any entities that involve context-sensitive keywords,
6087 // take another pass through the tokens to mark them as such.
6088 if (W.hasContextSensitiveKeywords()) {
6089 for (unsigned I = 0; I != NumTokens; ++I) {
6090 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
6091 continue;
6092
6093 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
6094 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006095 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006096 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
6097 if (Property->getPropertyAttributesAsWritten() != 0 &&
6098 llvm::StringSwitch<bool>(II->getName())
6099 .Case("readonly", true)
6100 .Case("assign", true)
6101 .Case("unsafe_unretained", true)
6102 .Case("readwrite", true)
6103 .Case("retain", true)
6104 .Case("copy", true)
6105 .Case("nonatomic", true)
6106 .Case("atomic", true)
6107 .Case("getter", true)
6108 .Case("setter", true)
6109 .Case("strong", true)
6110 .Case("weak", true)
6111 .Default(false))
6112 Tokens[I].int_data[0] = CXToken_Keyword;
6113 }
6114 continue;
6115 }
6116
6117 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6118 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6119 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6120 if (llvm::StringSwitch<bool>(II->getName())
6121 .Case("in", true)
6122 .Case("out", true)
6123 .Case("inout", true)
6124 .Case("oneway", true)
6125 .Case("bycopy", true)
6126 .Case("byref", true)
6127 .Default(false))
6128 Tokens[I].int_data[0] = CXToken_Keyword;
6129 continue;
6130 }
6131
6132 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6133 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6134 Tokens[I].int_data[0] = CXToken_Keyword;
6135 continue;
6136 }
6137 }
6138 }
6139}
6140
6141extern "C" {
6142
6143void clang_annotateTokens(CXTranslationUnit TU,
6144 CXToken *Tokens, unsigned NumTokens,
6145 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006146 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006147 LOG_BAD_TU(TU);
6148 return;
6149 }
6150 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006151 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006152 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006153 }
6154
6155 LOG_FUNC_SECTION {
6156 *Log << TU << ' ';
6157 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6158 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6159 *Log << clang_getRange(bloc, eloc);
6160 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006161
6162 // Any token we don't specifically annotate will have a NULL cursor.
6163 CXCursor C = clang_getNullCursor();
6164 for (unsigned I = 0; I != NumTokens; ++I)
6165 Cursors[I] = C;
6166
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006167 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006168 if (!CXXUnit)
6169 return;
6170
6171 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
6172
6173 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
6174 llvm::CrashRecoveryContext CRC;
6175 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
6176 GetSafetyThreadStackSize() * 2)) {
6177 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6178 }
6179}
6180
6181} // end: extern "C"
6182
6183//===----------------------------------------------------------------------===//
6184// Operations for querying linkage of a cursor.
6185//===----------------------------------------------------------------------===//
6186
6187extern "C" {
6188CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6189 if (!clang_isDeclaration(cursor.kind))
6190 return CXLinkage_Invalid;
6191
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006192 const Decl *D = cxcursor::getCursorDecl(cursor);
6193 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006194 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006195 case NoLinkage:
6196 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006197 case InternalLinkage: return CXLinkage_Internal;
6198 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6199 case ExternalLinkage: return CXLinkage_External;
6200 };
6201
6202 return CXLinkage_Invalid;
6203}
6204} // end: extern "C"
6205
6206//===----------------------------------------------------------------------===//
6207// Operations for querying language of a cursor.
6208//===----------------------------------------------------------------------===//
6209
6210static CXLanguageKind getDeclLanguage(const Decl *D) {
6211 if (!D)
6212 return CXLanguage_C;
6213
6214 switch (D->getKind()) {
6215 default:
6216 break;
6217 case Decl::ImplicitParam:
6218 case Decl::ObjCAtDefsField:
6219 case Decl::ObjCCategory:
6220 case Decl::ObjCCategoryImpl:
6221 case Decl::ObjCCompatibleAlias:
6222 case Decl::ObjCImplementation:
6223 case Decl::ObjCInterface:
6224 case Decl::ObjCIvar:
6225 case Decl::ObjCMethod:
6226 case Decl::ObjCProperty:
6227 case Decl::ObjCPropertyImpl:
6228 case Decl::ObjCProtocol:
6229 return CXLanguage_ObjC;
6230 case Decl::CXXConstructor:
6231 case Decl::CXXConversion:
6232 case Decl::CXXDestructor:
6233 case Decl::CXXMethod:
6234 case Decl::CXXRecord:
6235 case Decl::ClassTemplate:
6236 case Decl::ClassTemplatePartialSpecialization:
6237 case Decl::ClassTemplateSpecialization:
6238 case Decl::Friend:
6239 case Decl::FriendTemplate:
6240 case Decl::FunctionTemplate:
6241 case Decl::LinkageSpec:
6242 case Decl::Namespace:
6243 case Decl::NamespaceAlias:
6244 case Decl::NonTypeTemplateParm:
6245 case Decl::StaticAssert:
6246 case Decl::TemplateTemplateParm:
6247 case Decl::TemplateTypeParm:
6248 case Decl::UnresolvedUsingTypename:
6249 case Decl::UnresolvedUsingValue:
6250 case Decl::Using:
6251 case Decl::UsingDirective:
6252 case Decl::UsingShadow:
6253 return CXLanguage_CPlusPlus;
6254 }
6255
6256 return CXLanguage_C;
6257}
6258
6259extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006260
6261static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6262 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
6263 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00006264
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006265 switch (D->getAvailability()) {
6266 case AR_Available:
6267 case AR_NotYetIntroduced:
6268 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006269 return getCursorAvailabilityForDecl(
6270 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006271 return CXAvailability_Available;
6272
6273 case AR_Deprecated:
6274 return CXAvailability_Deprecated;
6275
6276 case AR_Unavailable:
6277 return CXAvailability_NotAvailable;
6278 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006279
6280 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006281}
6282
Guy Benyei11169dd2012-12-18 14:30:41 +00006283enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6284 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006285 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6286 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006287
6288 return CXAvailability_Available;
6289}
6290
6291static CXVersion convertVersion(VersionTuple In) {
6292 CXVersion Out = { -1, -1, -1 };
6293 if (In.empty())
6294 return Out;
6295
6296 Out.Major = In.getMajor();
6297
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006298 Optional<unsigned> Minor = In.getMinor();
6299 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006300 Out.Minor = *Minor;
6301 else
6302 return Out;
6303
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006304 Optional<unsigned> Subminor = In.getSubminor();
6305 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006306 Out.Subminor = *Subminor;
6307
6308 return Out;
6309}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006310
6311static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6312 int *always_deprecated,
6313 CXString *deprecated_message,
6314 int *always_unavailable,
6315 CXString *unavailable_message,
6316 CXPlatformAvailability *availability,
6317 int availability_size) {
6318 bool HadAvailAttr = false;
6319 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006320 for (auto A : D->attrs()) {
6321 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006322 HadAvailAttr = true;
6323 if (always_deprecated)
6324 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006325 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006326 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006327 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006328 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006329 continue;
6330 }
6331
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006332 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006333 HadAvailAttr = true;
6334 if (always_unavailable)
6335 *always_unavailable = 1;
6336 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006337 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006338 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6339 }
6340 continue;
6341 }
6342
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006343 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006344 HadAvailAttr = true;
6345 if (N < availability_size) {
6346 availability[N].Platform
6347 = cxstring::createDup(Avail->getPlatform()->getName());
6348 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6349 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6350 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6351 availability[N].Unavailable = Avail->getUnavailable();
6352 availability[N].Message = cxstring::createDup(Avail->getMessage());
6353 }
6354 ++N;
6355 }
6356 }
6357
6358 if (!HadAvailAttr)
6359 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6360 return getCursorPlatformAvailabilityForDecl(
6361 cast<Decl>(EnumConst->getDeclContext()),
6362 always_deprecated,
6363 deprecated_message,
6364 always_unavailable,
6365 unavailable_message,
6366 availability,
6367 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006368
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006369 return N;
6370}
6371
Guy Benyei11169dd2012-12-18 14:30:41 +00006372int clang_getCursorPlatformAvailability(CXCursor cursor,
6373 int *always_deprecated,
6374 CXString *deprecated_message,
6375 int *always_unavailable,
6376 CXString *unavailable_message,
6377 CXPlatformAvailability *availability,
6378 int availability_size) {
6379 if (always_deprecated)
6380 *always_deprecated = 0;
6381 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006382 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006383 if (always_unavailable)
6384 *always_unavailable = 0;
6385 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006386 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006387
Guy Benyei11169dd2012-12-18 14:30:41 +00006388 if (!clang_isDeclaration(cursor.kind))
6389 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006390
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006391 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006392 if (!D)
6393 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006394
6395 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6396 deprecated_message,
6397 always_unavailable,
6398 unavailable_message,
6399 availability,
6400 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006401}
6402
6403void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6404 clang_disposeString(availability->Platform);
6405 clang_disposeString(availability->Message);
6406}
6407
6408CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6409 if (clang_isDeclaration(cursor.kind))
6410 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6411
6412 return CXLanguage_Invalid;
6413}
6414
6415 /// \brief If the given cursor is the "templated" declaration
6416 /// descibing a class or function template, return the class or
6417 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006418static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006419 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006420 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006421
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006422 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006423 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6424 return FunTmpl;
6425
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006426 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006427 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6428 return ClassTmpl;
6429
6430 return D;
6431}
6432
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006433
6434enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
6435 StorageClass sc = SC_None;
6436 const Decl *D = getCursorDecl(C);
6437 if (D) {
6438 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
6439 sc = FD->getStorageClass();
6440 } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
6441 sc = VD->getStorageClass();
6442 } else {
6443 return CX_SC_Invalid;
6444 }
6445 } else {
6446 return CX_SC_Invalid;
6447 }
6448 switch (sc) {
6449 case SC_None:
6450 return CX_SC_None;
6451 case SC_Extern:
6452 return CX_SC_Extern;
6453 case SC_Static:
6454 return CX_SC_Static;
6455 case SC_PrivateExtern:
6456 return CX_SC_PrivateExtern;
6457 case SC_OpenCLWorkGroupLocal:
6458 return CX_SC_OpenCLWorkGroupLocal;
6459 case SC_Auto:
6460 return CX_SC_Auto;
6461 case SC_Register:
6462 return CX_SC_Register;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006463 }
Kaelyn Takataab61e702014-10-15 18:03:26 +00006464 llvm_unreachable("Unhandled storage class!");
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006465}
6466
Guy Benyei11169dd2012-12-18 14:30:41 +00006467CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6468 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006469 if (const Decl *D = getCursorDecl(cursor)) {
6470 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006471 if (!DC)
6472 return clang_getNullCursor();
6473
6474 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6475 getCursorTU(cursor));
6476 }
6477 }
6478
6479 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006480 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006481 return MakeCXCursor(D, getCursorTU(cursor));
6482 }
6483
6484 return clang_getNullCursor();
6485}
6486
6487CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6488 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006489 if (const Decl *D = getCursorDecl(cursor)) {
6490 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006491 if (!DC)
6492 return clang_getNullCursor();
6493
6494 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6495 getCursorTU(cursor));
6496 }
6497 }
6498
6499 // FIXME: Note that we can't easily compute the lexical context of a
6500 // statement or expression, so we return nothing.
6501 return clang_getNullCursor();
6502}
6503
6504CXFile clang_getIncludedFile(CXCursor cursor) {
6505 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006506 return nullptr;
6507
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006508 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006509 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006510}
6511
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006512unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6513 if (C.kind != CXCursor_ObjCPropertyDecl)
6514 return CXObjCPropertyAttr_noattr;
6515
6516 unsigned Result = CXObjCPropertyAttr_noattr;
6517 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6518 ObjCPropertyDecl::PropertyAttributeKind Attr =
6519 PD->getPropertyAttributesAsWritten();
6520
6521#define SET_CXOBJCPROP_ATTR(A) \
6522 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6523 Result |= CXObjCPropertyAttr_##A
6524 SET_CXOBJCPROP_ATTR(readonly);
6525 SET_CXOBJCPROP_ATTR(getter);
6526 SET_CXOBJCPROP_ATTR(assign);
6527 SET_CXOBJCPROP_ATTR(readwrite);
6528 SET_CXOBJCPROP_ATTR(retain);
6529 SET_CXOBJCPROP_ATTR(copy);
6530 SET_CXOBJCPROP_ATTR(nonatomic);
6531 SET_CXOBJCPROP_ATTR(setter);
6532 SET_CXOBJCPROP_ATTR(atomic);
6533 SET_CXOBJCPROP_ATTR(weak);
6534 SET_CXOBJCPROP_ATTR(strong);
6535 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6536#undef SET_CXOBJCPROP_ATTR
6537
6538 return Result;
6539}
6540
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006541unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6542 if (!clang_isDeclaration(C.kind))
6543 return CXObjCDeclQualifier_None;
6544
6545 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6546 const Decl *D = getCursorDecl(C);
6547 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6548 QT = MD->getObjCDeclQualifier();
6549 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6550 QT = PD->getObjCDeclQualifier();
6551 if (QT == Decl::OBJC_TQ_None)
6552 return CXObjCDeclQualifier_None;
6553
6554 unsigned Result = CXObjCDeclQualifier_None;
6555 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6556 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6557 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6558 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6559 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6560 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6561
6562 return Result;
6563}
6564
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006565unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6566 if (!clang_isDeclaration(C.kind))
6567 return 0;
6568
6569 const Decl *D = getCursorDecl(C);
6570 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6571 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6572 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6573 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6574
6575 return 0;
6576}
6577
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006578unsigned clang_Cursor_isVariadic(CXCursor C) {
6579 if (!clang_isDeclaration(C.kind))
6580 return 0;
6581
6582 const Decl *D = getCursorDecl(C);
6583 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6584 return FD->isVariadic();
6585 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6586 return MD->isVariadic();
6587
6588 return 0;
6589}
6590
Guy Benyei11169dd2012-12-18 14:30:41 +00006591CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6592 if (!clang_isDeclaration(C.kind))
6593 return clang_getNullRange();
6594
6595 const Decl *D = getCursorDecl(C);
6596 ASTContext &Context = getCursorContext(C);
6597 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6598 if (!RC)
6599 return clang_getNullRange();
6600
6601 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6602}
6603
6604CXString clang_Cursor_getRawCommentText(CXCursor C) {
6605 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006606 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006607
6608 const Decl *D = getCursorDecl(C);
6609 ASTContext &Context = getCursorContext(C);
6610 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6611 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6612 StringRef();
6613
6614 // Don't duplicate the string because RawText points directly into source
6615 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006616 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006617}
6618
6619CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6620 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006621 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006622
6623 const Decl *D = getCursorDecl(C);
6624 const ASTContext &Context = getCursorContext(C);
6625 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6626
6627 if (RC) {
6628 StringRef BriefText = RC->getBriefText(Context);
6629
6630 // Don't duplicate the string because RawComment ensures that this memory
6631 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006632 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006633 }
6634
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006635 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006636}
6637
Guy Benyei11169dd2012-12-18 14:30:41 +00006638CXModule clang_Cursor_getModule(CXCursor C) {
6639 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006640 if (const ImportDecl *ImportD =
6641 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006642 return ImportD->getImportedModule();
6643 }
6644
Craig Topper69186e72014-06-08 08:38:04 +00006645 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006646}
6647
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006648CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6649 if (isNotUsableTU(TU)) {
6650 LOG_BAD_TU(TU);
6651 return nullptr;
6652 }
6653 if (!File)
6654 return nullptr;
6655 FileEntry *FE = static_cast<FileEntry *>(File);
6656
6657 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6658 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6659 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6660
Richard Smithfeb54b62014-10-23 02:01:19 +00006661 return Header.getModule();
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006662}
6663
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006664CXFile clang_Module_getASTFile(CXModule CXMod) {
6665 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006666 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006667 Module *Mod = static_cast<Module*>(CXMod);
6668 return const_cast<FileEntry *>(Mod->getASTFile());
6669}
6670
Guy Benyei11169dd2012-12-18 14:30:41 +00006671CXModule clang_Module_getParent(CXModule CXMod) {
6672 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006673 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006674 Module *Mod = static_cast<Module*>(CXMod);
6675 return Mod->Parent;
6676}
6677
6678CXString clang_Module_getName(CXModule CXMod) {
6679 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006680 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006681 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006682 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006683}
6684
6685CXString clang_Module_getFullName(CXModule CXMod) {
6686 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006687 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006688 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006689 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006690}
6691
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006692int clang_Module_isSystem(CXModule CXMod) {
6693 if (!CXMod)
6694 return 0;
6695 Module *Mod = static_cast<Module*>(CXMod);
6696 return Mod->IsSystem;
6697}
6698
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006699unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6700 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006701 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006702 LOG_BAD_TU(TU);
6703 return 0;
6704 }
6705 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006706 return 0;
6707 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006708 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6709 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6710 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006711}
6712
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006713CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6714 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006715 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006716 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006717 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006718 }
6719 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006720 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006721 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006722 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006723
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006724 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6725 if (Index < TopHeaders.size())
6726 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006727
Craig Topper69186e72014-06-08 08:38:04 +00006728 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006729}
6730
6731} // end: extern "C"
6732
6733//===----------------------------------------------------------------------===//
6734// C++ AST instrospection.
6735//===----------------------------------------------------------------------===//
6736
6737extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006738unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6739 if (!clang_isDeclaration(C.kind))
6740 return 0;
6741
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006742 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006743 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006744 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006745 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6746}
6747
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006748unsigned clang_CXXMethod_isConst(CXCursor C) {
6749 if (!clang_isDeclaration(C.kind))
6750 return 0;
6751
6752 const Decl *D = cxcursor::getCursorDecl(C);
6753 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006754 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006755 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6756}
6757
Guy Benyei11169dd2012-12-18 14:30:41 +00006758unsigned clang_CXXMethod_isStatic(CXCursor C) {
6759 if (!clang_isDeclaration(C.kind))
6760 return 0;
6761
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006762 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006763 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006764 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006765 return (Method && Method->isStatic()) ? 1 : 0;
6766}
6767
6768unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6769 if (!clang_isDeclaration(C.kind))
6770 return 0;
6771
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006772 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006773 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006774 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006775 return (Method && Method->isVirtual()) ? 1 : 0;
6776}
6777} // end: extern "C"
6778
6779//===----------------------------------------------------------------------===//
6780// Attribute introspection.
6781//===----------------------------------------------------------------------===//
6782
6783extern "C" {
6784CXType clang_getIBOutletCollectionType(CXCursor C) {
6785 if (C.kind != CXCursor_IBOutletCollectionAttr)
6786 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6787
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006788 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006789 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6790
6791 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6792}
6793} // end: extern "C"
6794
6795//===----------------------------------------------------------------------===//
6796// Inspecting memory usage.
6797//===----------------------------------------------------------------------===//
6798
6799typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6800
6801static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6802 enum CXTUResourceUsageKind k,
6803 unsigned long amount) {
6804 CXTUResourceUsageEntry entry = { k, amount };
6805 entries.push_back(entry);
6806}
6807
6808extern "C" {
6809
6810const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6811 const char *str = "";
6812 switch (kind) {
6813 case CXTUResourceUsage_AST:
6814 str = "ASTContext: expressions, declarations, and types";
6815 break;
6816 case CXTUResourceUsage_Identifiers:
6817 str = "ASTContext: identifiers";
6818 break;
6819 case CXTUResourceUsage_Selectors:
6820 str = "ASTContext: selectors";
6821 break;
6822 case CXTUResourceUsage_GlobalCompletionResults:
6823 str = "Code completion: cached global results";
6824 break;
6825 case CXTUResourceUsage_SourceManagerContentCache:
6826 str = "SourceManager: content cache allocator";
6827 break;
6828 case CXTUResourceUsage_AST_SideTables:
6829 str = "ASTContext: side tables";
6830 break;
6831 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6832 str = "SourceManager: malloc'ed memory buffers";
6833 break;
6834 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6835 str = "SourceManager: mmap'ed memory buffers";
6836 break;
6837 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6838 str = "ExternalASTSource: malloc'ed memory buffers";
6839 break;
6840 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6841 str = "ExternalASTSource: mmap'ed memory buffers";
6842 break;
6843 case CXTUResourceUsage_Preprocessor:
6844 str = "Preprocessor: malloc'ed memory";
6845 break;
6846 case CXTUResourceUsage_PreprocessingRecord:
6847 str = "Preprocessor: PreprocessingRecord";
6848 break;
6849 case CXTUResourceUsage_SourceManager_DataStructures:
6850 str = "SourceManager: data structures and tables";
6851 break;
6852 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6853 str = "Preprocessor: header search tables";
6854 break;
6855 }
6856 return str;
6857}
6858
6859CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006860 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006861 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006862 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00006863 return usage;
6864 }
6865
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006866 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006867 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006868 ASTContext &astContext = astUnit->getASTContext();
6869
6870 // How much memory is used by AST nodes and types?
6871 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6872 (unsigned long) astContext.getASTAllocatedMemory());
6873
6874 // How much memory is used by identifiers?
6875 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6876 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6877
6878 // How much memory is used for selectors?
6879 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6880 (unsigned long) astContext.Selectors.getTotalMemory());
6881
6882 // How much memory is used by ASTContext's side tables?
6883 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6884 (unsigned long) astContext.getSideTableAllocatedMemory());
6885
6886 // How much memory is used for caching global code completion results?
6887 unsigned long completionBytes = 0;
6888 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00006889 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006890 completionBytes = completionAllocator->getTotalMemory();
6891 }
6892 createCXTUResourceUsageEntry(*entries,
6893 CXTUResourceUsage_GlobalCompletionResults,
6894 completionBytes);
6895
6896 // How much memory is being used by SourceManager's content cache?
6897 createCXTUResourceUsageEntry(*entries,
6898 CXTUResourceUsage_SourceManagerContentCache,
6899 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6900
6901 // How much memory is being used by the MemoryBuffer's in SourceManager?
6902 const SourceManager::MemoryBufferSizes &srcBufs =
6903 astUnit->getSourceManager().getMemoryBufferSizes();
6904
6905 createCXTUResourceUsageEntry(*entries,
6906 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6907 (unsigned long) srcBufs.malloc_bytes);
6908 createCXTUResourceUsageEntry(*entries,
6909 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6910 (unsigned long) srcBufs.mmap_bytes);
6911 createCXTUResourceUsageEntry(*entries,
6912 CXTUResourceUsage_SourceManager_DataStructures,
6913 (unsigned long) astContext.getSourceManager()
6914 .getDataStructureSizes());
6915
6916 // How much memory is being used by the ExternalASTSource?
6917 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6918 const ExternalASTSource::MemoryBufferSizes &sizes =
6919 esrc->getMemoryBufferSizes();
6920
6921 createCXTUResourceUsageEntry(*entries,
6922 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6923 (unsigned long) sizes.malloc_bytes);
6924 createCXTUResourceUsageEntry(*entries,
6925 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6926 (unsigned long) sizes.mmap_bytes);
6927 }
6928
6929 // How much memory is being used by the Preprocessor?
6930 Preprocessor &pp = astUnit->getPreprocessor();
6931 createCXTUResourceUsageEntry(*entries,
6932 CXTUResourceUsage_Preprocessor,
6933 pp.getTotalMemory());
6934
6935 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6936 createCXTUResourceUsageEntry(*entries,
6937 CXTUResourceUsage_PreprocessingRecord,
6938 pRec->getTotalMemory());
6939 }
6940
6941 createCXTUResourceUsageEntry(*entries,
6942 CXTUResourceUsage_Preprocessor_HeaderSearch,
6943 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00006944
Guy Benyei11169dd2012-12-18 14:30:41 +00006945 CXTUResourceUsage usage = { (void*) entries.get(),
6946 (unsigned) entries->size(),
Alexander Kornienko6ee521c2015-01-23 15:36:10 +00006947 !entries->empty() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00006948 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00006949 return usage;
6950}
6951
6952void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6953 if (usage.data)
6954 delete (MemUsageEntries*) usage.data;
6955}
6956
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006957CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6958 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006959 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00006960 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006961
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006962 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006963 LOG_BAD_TU(TU);
6964 return skipped;
6965 }
6966
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006967 if (!file)
6968 return skipped;
6969
6970 ASTUnit *astUnit = cxtu::getASTUnit(TU);
6971 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6972 if (!ppRec)
6973 return skipped;
6974
6975 ASTContext &Ctx = astUnit->getASTContext();
6976 SourceManager &sm = Ctx.getSourceManager();
6977 FileEntry *fileEntry = static_cast<FileEntry *>(file);
6978 FileID wantedFileID = sm.translateFile(fileEntry);
6979
6980 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6981 std::vector<SourceRange> wantedRanges;
6982 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6983 i != ei; ++i) {
6984 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6985 wantedRanges.push_back(*i);
6986 }
6987
6988 skipped->count = wantedRanges.size();
6989 skipped->ranges = new CXSourceRange[skipped->count];
6990 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
6991 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
6992
6993 return skipped;
6994}
6995
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006996void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
6997 if (ranges) {
6998 delete[] ranges->ranges;
6999 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007000 }
7001}
7002
Guy Benyei11169dd2012-12-18 14:30:41 +00007003} // end extern "C"
7004
7005void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
7006 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
7007 for (unsigned I = 0; I != Usage.numEntries; ++I)
7008 fprintf(stderr, " %s: %lu\n",
7009 clang_getTUResourceUsageName(Usage.entries[I].kind),
7010 Usage.entries[I].amount);
7011
7012 clang_disposeCXTUResourceUsage(Usage);
7013}
7014
7015//===----------------------------------------------------------------------===//
7016// Misc. utility functions.
7017//===----------------------------------------------------------------------===//
7018
7019/// Default to using an 8 MB stack size on "safety" threads.
7020static unsigned SafetyStackThreadSize = 8 << 20;
7021
7022namespace clang {
7023
7024bool RunSafely(llvm::CrashRecoveryContext &CRC,
7025 void (*Fn)(void*), void *UserData,
7026 unsigned Size) {
7027 if (!Size)
7028 Size = GetSafetyThreadStackSize();
7029 if (Size)
7030 return CRC.RunSafelyOnThread(Fn, UserData, Size);
7031 return CRC.RunSafely(Fn, UserData);
7032}
7033
7034unsigned GetSafetyThreadStackSize() {
7035 return SafetyStackThreadSize;
7036}
7037
7038void SetSafetyThreadStackSize(unsigned Value) {
7039 SafetyStackThreadSize = Value;
7040}
7041
7042}
7043
7044void clang::setThreadBackgroundPriority() {
7045 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
7046 return;
7047
Alp Toker1a86ad22014-07-06 06:24:00 +00007048#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00007049 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
7050#endif
7051}
7052
7053void cxindex::printDiagsToStderr(ASTUnit *Unit) {
7054 if (!Unit)
7055 return;
7056
7057 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
7058 DEnd = Unit->stored_diag_end();
7059 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00007060 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00007061 CXString Msg = clang_formatDiagnostic(&Diag,
7062 clang_defaultDiagnosticDisplayOptions());
7063 fprintf(stderr, "%s\n", clang_getCString(Msg));
7064 clang_disposeString(Msg);
7065 }
7066#ifdef LLVM_ON_WIN32
7067 // On Windows, force a flush, since there may be multiple copies of
7068 // stderr and stdout in the file system, all with different buffers
7069 // but writing to the same device.
7070 fflush(stderr);
7071#endif
7072}
7073
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007074MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
7075 SourceLocation MacroDefLoc,
7076 CXTranslationUnit TU){
7077 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007078 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007079 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007080 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007081
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007082 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007083 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007084 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007085 if (MD) {
7086 for (MacroDirective::DefInfo
7087 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
7088 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
7089 return Def.getMacroInfo();
7090 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007091 }
7092
Craig Topper69186e72014-06-08 08:38:04 +00007093 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007094}
7095
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007096const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
7097 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007098 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007099 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007100 const IdentifierInfo *II = MacroDef->getName();
7101 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00007102 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007103
7104 return getMacroInfo(*II, MacroDef->getLocation(), TU);
7105}
7106
7107MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
7108 const Token &Tok,
7109 CXTranslationUnit TU) {
7110 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007111 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007112 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00007113 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007114
7115 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007116 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007117 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
7118 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007119 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007120
7121 // Check that the token is inside the definition and not its argument list.
7122 SourceManager &SM = Unit->getSourceManager();
7123 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00007124 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007125 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00007126 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007127
7128 Preprocessor &PP = Unit->getPreprocessor();
7129 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
7130 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00007131 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007132
Alp Toker2d57cea2014-05-17 04:53:25 +00007133 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007134 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007135 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007136
7137 // Check that the identifier is not one of the macro arguments.
7138 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00007139 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007140
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007141 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
7142 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00007143 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007144
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007145 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007146}
7147
7148MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
7149 SourceLocation Loc,
7150 CXTranslationUnit TU) {
7151 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007152 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007153
7154 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007155 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007156 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007157 Preprocessor &PP = Unit->getPreprocessor();
7158 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00007159 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007160 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7161 Token Tok;
7162 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00007163 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007164
7165 return checkForMacroInMacroDefinition(MI, Tok, TU);
7166}
7167
Guy Benyei11169dd2012-12-18 14:30:41 +00007168extern "C" {
7169
7170CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007171 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00007172}
7173
7174} // end: extern "C"
7175
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007176Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7177 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007178 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007179 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007180 if (Unit->isMainFileAST())
7181 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007182 return *this;
7183 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007184 } else {
7185 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007186 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007187 return *this;
7188}
7189
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007190Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7191 *this << FE->getName();
7192 return *this;
7193}
7194
7195Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7196 CXString cursorName = clang_getCursorDisplayName(cursor);
7197 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7198 clang_disposeString(cursorName);
7199 return *this;
7200}
7201
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007202Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7203 CXFile File;
7204 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007205 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007206 CXString FileName = clang_getFileName(File);
7207 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7208 clang_disposeString(FileName);
7209 return *this;
7210}
7211
7212Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7213 CXSourceLocation BLoc = clang_getRangeStart(range);
7214 CXSourceLocation ELoc = clang_getRangeEnd(range);
7215
7216 CXFile BFile;
7217 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007218 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007219
7220 CXFile EFile;
7221 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007222 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007223
7224 CXString BFileName = clang_getFileName(BFile);
7225 if (BFile == EFile) {
7226 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7227 BLine, BColumn, ELine, EColumn);
7228 } else {
7229 CXString EFileName = clang_getFileName(EFile);
7230 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7231 BLine, BColumn)
7232 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7233 ELine, EColumn);
7234 clang_disposeString(EFileName);
7235 }
7236 clang_disposeString(BFileName);
7237 return *this;
7238}
7239
7240Logger &cxindex::Logger::operator<<(CXString Str) {
7241 *this << clang_getCString(Str);
7242 return *this;
7243}
7244
7245Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7246 LogOS << Fmt;
7247 return *this;
7248}
7249
Chandler Carruth37ad2582014-06-27 15:14:39 +00007250static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7251
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007252cxindex::Logger::~Logger() {
7253 LogOS.flush();
7254
Chandler Carruth37ad2582014-06-27 15:14:39 +00007255 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007256
7257 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7258
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007259 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007260 OS << "[libclang:" << Name << ':';
7261
Alp Toker1a86ad22014-07-06 06:24:00 +00007262#ifdef USE_DARWIN_THREADS
7263 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007264 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7265 OS << tid << ':';
7266#endif
7267
7268 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7269 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
7270 OS << Msg.str() << '\n';
7271
7272 if (Trace) {
Zachary Turner1fe2a8d2015-03-05 19:15:09 +00007273 llvm::sys::PrintStackTrace(OS);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007274 OS << "--------------------------------------------------\n";
7275 }
7276}