blob: df0ed2ad65ddc9575e212a50027224c2754193d3 [file] [log] [blame]
Guy Benyei11169dd2012-12-18 14:30:41 +00001//===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the main API hooks in the Clang-C Source Indexing
11// library.
12//
13//===----------------------------------------------------------------------===//
14
15#include "CIndexer.h"
16#include "CIndexDiagnostic.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000017#include "CLog.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000018#include "CXCursor.h"
19#include "CXSourceLocation.h"
20#include "CXString.h"
21#include "CXTranslationUnit.h"
22#include "CXType.h"
23#include "CursorVisitor.h"
David Blaikie0a4e61f2013-09-13 18:32:52 +000024#include "clang/AST/Attr.h"
Eli Bendersky44a206f2014-07-31 18:04:56 +000025#include "clang/AST/Mangle.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000026#include "clang/AST/StmtVisitor.h"
27#include "clang/Basic/Diagnostic.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000028#include "clang/Basic/DiagnosticCategories.h"
29#include "clang/Basic/DiagnosticIDs.h"
Eli Bendersky79759592014-08-01 15:01:10 +000030#include "clang/Basic/TargetInfo.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000031#include "clang/Basic/Version.h"
32#include "clang/Frontend/ASTUnit.h"
33#include "clang/Frontend/CompilerInstance.h"
34#include "clang/Frontend/FrontendDiagnostic.h"
Dmitri Gribenko9e605112013-11-13 22:16:51 +000035#include "clang/Index/CommentToXML.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000036#include "clang/Lex/HeaderSearch.h"
37#include "clang/Lex/Lexer.h"
38#include "clang/Lex/PreprocessingRecord.h"
39#include "clang/Lex/Preprocessor.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000040#include "clang/Serialization/SerializationDiagnostic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000041#include "llvm/ADT/Optional.h"
42#include "llvm/ADT/STLExtras.h"
43#include "llvm/ADT/StringSwitch.h"
Alp Toker1d257e12014-06-04 03:28:55 +000044#include "llvm/Config/llvm-config.h"
Eli Bendersky79759592014-08-01 15:01:10 +000045#include "llvm/IR/DataLayout.h"
46#include "llvm/IR/Mangler.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000047#include "llvm/Support/Compiler.h"
48#include "llvm/Support/CrashRecoveryContext.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000049#include "llvm/Support/Format.h"
Chandler Carruth37ad2582014-06-27 15:14:39 +000050#include "llvm/Support/ManagedStatic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000051#include "llvm/Support/MemoryBuffer.h"
52#include "llvm/Support/Mutex.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000053#include "llvm/Support/Program.h"
54#include "llvm/Support/SaveAndRestore.h"
55#include "llvm/Support/Signals.h"
56#include "llvm/Support/Threading.h"
57#include "llvm/Support/Timer.h"
58#include "llvm/Support/raw_ostream.h"
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000059
Alp Toker1a86ad22014-07-06 06:24:00 +000060#if LLVM_ENABLE_THREADS != 0 && defined(__APPLE__)
61#define USE_DARWIN_THREADS
62#endif
63
64#ifdef USE_DARWIN_THREADS
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000065#include <pthread.h>
66#endif
Guy Benyei11169dd2012-12-18 14:30:41 +000067
68using namespace clang;
69using namespace clang::cxcursor;
Guy Benyei11169dd2012-12-18 14:30:41 +000070using namespace clang::cxtu;
71using namespace clang::cxindex;
72
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000073CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) {
74 if (!AU)
Craig Topper69186e72014-06-08 08:38:04 +000075 return nullptr;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000076 assert(CIdx);
Guy Benyei11169dd2012-12-18 14:30:41 +000077 CXTranslationUnit D = new CXTranslationUnitImpl();
78 D->CIdx = CIdx;
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000079 D->TheASTUnit = AU;
Dmitri Gribenko74895212013-02-03 13:52:47 +000080 D->StringPool = new cxstring::CXStringPool();
Craig Topper69186e72014-06-08 08:38:04 +000081 D->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000082 D->OverridenCursorsPool = createOverridenCXCursorsPool();
Craig Topper69186e72014-06-08 08:38:04 +000083 D->CommentToXML = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000084 return D;
85}
86
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000087bool cxtu::isASTReadError(ASTUnit *AU) {
88 for (ASTUnit::stored_diag_iterator D = AU->stored_diag_begin(),
89 DEnd = AU->stored_diag_end();
90 D != DEnd; ++D) {
91 if (D->getLevel() >= DiagnosticsEngine::Error &&
92 DiagnosticIDs::getCategoryNumberForDiag(D->getID()) ==
93 diag::DiagCat_AST_Deserialization_Issue)
94 return true;
95 }
96 return false;
97}
98
Guy Benyei11169dd2012-12-18 14:30:41 +000099cxtu::CXTUOwner::~CXTUOwner() {
100 if (TU)
101 clang_disposeTranslationUnit(TU);
102}
103
104/// \brief Compare two source ranges to determine their relative position in
105/// the translation unit.
106static RangeComparisonResult RangeCompare(SourceManager &SM,
107 SourceRange R1,
108 SourceRange R2) {
109 assert(R1.isValid() && "First range is invalid?");
110 assert(R2.isValid() && "Second range is invalid?");
111 if (R1.getEnd() != R2.getBegin() &&
112 SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
113 return RangeBefore;
114 if (R2.getEnd() != R1.getBegin() &&
115 SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
116 return RangeAfter;
117 return RangeOverlap;
118}
119
120/// \brief Determine if a source location falls within, before, or after a
121/// a given source range.
122static RangeComparisonResult LocationCompare(SourceManager &SM,
123 SourceLocation L, SourceRange R) {
124 assert(R.isValid() && "First range is invalid?");
125 assert(L.isValid() && "Second range is invalid?");
126 if (L == R.getBegin() || L == R.getEnd())
127 return RangeOverlap;
128 if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
129 return RangeBefore;
130 if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
131 return RangeAfter;
132 return RangeOverlap;
133}
134
135/// \brief Translate a Clang source range into a CIndex source range.
136///
137/// Clang internally represents ranges where the end location points to the
138/// start of the token at the end. However, for external clients it is more
139/// useful to have a CXSourceRange be a proper half-open interval. This routine
140/// does the appropriate translation.
141CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
142 const LangOptions &LangOpts,
143 const CharSourceRange &R) {
144 // We want the last character in this location, so we will adjust the
145 // location accordingly.
146 SourceLocation EndLoc = R.getEnd();
147 if (EndLoc.isValid() && EndLoc.isMacroID() && !SM.isMacroArgExpansion(EndLoc))
148 EndLoc = SM.getExpansionRange(EndLoc).second;
149 if (R.isTokenRange() && !EndLoc.isInvalid()) {
150 unsigned Length = Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc),
151 SM, LangOpts);
152 EndLoc = EndLoc.getLocWithOffset(Length);
153 }
154
Bill Wendlingeade3622013-01-23 08:25:41 +0000155 CXSourceRange Result = {
Dmitri Gribenkof9304482013-01-23 15:56:07 +0000156 { &SM, &LangOpts },
Bill Wendlingeade3622013-01-23 08:25:41 +0000157 R.getBegin().getRawEncoding(),
158 EndLoc.getRawEncoding()
159 };
Guy Benyei11169dd2012-12-18 14:30:41 +0000160 return Result;
161}
162
163//===----------------------------------------------------------------------===//
164// Cursor visitor.
165//===----------------------------------------------------------------------===//
166
167static SourceRange getRawCursorExtent(CXCursor C);
168static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
169
170
171RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
172 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
173}
174
175/// \brief Visit the given cursor and, if requested by the visitor,
176/// its children.
177///
178/// \param Cursor the cursor to visit.
179///
180/// \param CheckedRegionOfInterest if true, then the caller already checked
181/// that this cursor is within the region of interest.
182///
183/// \returns true if the visitation should be aborted, false if it
184/// should continue.
185bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
186 if (clang_isInvalid(Cursor.kind))
187 return false;
188
189 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000190 const Decl *D = getCursorDecl(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000191 if (!D) {
192 assert(0 && "Invalid declaration cursor");
193 return true; // abort.
194 }
195
196 // Ignore implicit declarations, unless it's an objc method because
197 // currently we should report implicit methods for properties when indexing.
198 if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
199 return false;
200 }
201
202 // If we have a range of interest, and this cursor doesn't intersect with it,
203 // we're done.
204 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
205 SourceRange Range = getRawCursorExtent(Cursor);
206 if (Range.isInvalid() || CompareRegionOfInterest(Range))
207 return false;
208 }
209
210 switch (Visitor(Cursor, Parent, ClientData)) {
211 case CXChildVisit_Break:
212 return true;
213
214 case CXChildVisit_Continue:
215 return false;
216
217 case CXChildVisit_Recurse: {
218 bool ret = VisitChildren(Cursor);
219 if (PostChildrenVisitor)
220 if (PostChildrenVisitor(Cursor, ClientData))
221 return true;
222 return ret;
223 }
224 }
225
226 llvm_unreachable("Invalid CXChildVisitResult!");
227}
228
229static bool visitPreprocessedEntitiesInRange(SourceRange R,
230 PreprocessingRecord &PPRec,
231 CursorVisitor &Visitor) {
232 SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
233 FileID FID;
234
235 if (!Visitor.shouldVisitIncludedEntities()) {
236 // If the begin/end of the range lie in the same FileID, do the optimization
237 // where we skip preprocessed entities that do not come from the same FileID.
238 FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
239 if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
240 FID = FileID();
241 }
242
Benjamin Kramerb4ef6682015-02-06 17:25:10 +0000243 const auto &Entities = PPRec.getPreprocessedEntitiesInRange(R);
244 return Visitor.visitPreprocessedEntities(Entities.begin(), Entities.end(),
Guy Benyei11169dd2012-12-18 14:30:41 +0000245 PPRec, FID);
246}
247
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000248bool CursorVisitor::visitFileRegion() {
Guy Benyei11169dd2012-12-18 14:30:41 +0000249 if (RegionOfInterest.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000250 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000251
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000252 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000253 SourceManager &SM = Unit->getSourceManager();
254
255 std::pair<FileID, unsigned>
256 Begin = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getBegin())),
257 End = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getEnd()));
258
259 if (End.first != Begin.first) {
260 // If the end does not reside in the same file, try to recover by
261 // picking the end of the file of begin location.
262 End.first = Begin.first;
263 End.second = SM.getFileIDSize(Begin.first);
264 }
265
266 assert(Begin.first == End.first);
267 if (Begin.second > End.second)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000268 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000269
270 FileID File = Begin.first;
271 unsigned Offset = Begin.second;
272 unsigned Length = End.second - Begin.second;
273
274 if (!VisitDeclsOnly && !VisitPreprocessorLast)
275 if (visitPreprocessedEntitiesInRegion())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000276 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000277
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000278 if (visitDeclsFromFileRegion(File, Offset, Length))
279 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000280
281 if (!VisitDeclsOnly && VisitPreprocessorLast)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000282 return visitPreprocessedEntitiesInRegion();
283
284 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000285}
286
287static bool isInLexicalContext(Decl *D, DeclContext *DC) {
288 if (!DC)
289 return false;
290
291 for (DeclContext *DeclDC = D->getLexicalDeclContext();
292 DeclDC; DeclDC = DeclDC->getLexicalParent()) {
293 if (DeclDC == DC)
294 return true;
295 }
296 return false;
297}
298
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000299bool CursorVisitor::visitDeclsFromFileRegion(FileID File,
Guy Benyei11169dd2012-12-18 14:30:41 +0000300 unsigned Offset, unsigned Length) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000301 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000302 SourceManager &SM = Unit->getSourceManager();
303 SourceRange Range = RegionOfInterest;
304
305 SmallVector<Decl *, 16> Decls;
306 Unit->findFileRegionDecls(File, Offset, Length, Decls);
307
308 // If we didn't find any file level decls for the file, try looking at the
309 // file that it was included from.
310 while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
311 bool Invalid = false;
312 const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
313 if (Invalid)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000314 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000315
316 SourceLocation Outer;
317 if (SLEntry.isFile())
318 Outer = SLEntry.getFile().getIncludeLoc();
319 else
320 Outer = SLEntry.getExpansion().getExpansionLocStart();
321 if (Outer.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000322 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000323
Benjamin Kramer867ea1d2014-03-02 13:01:17 +0000324 std::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
Guy Benyei11169dd2012-12-18 14:30:41 +0000325 Length = 0;
326 Unit->findFileRegionDecls(File, Offset, Length, Decls);
327 }
328
329 assert(!Decls.empty());
330
331 bool VisitedAtLeastOnce = false;
Craig Topper69186e72014-06-08 08:38:04 +0000332 DeclContext *CurDC = nullptr;
Craig Topper2341c0d2013-07-04 03:08:24 +0000333 SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
334 for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000335 Decl *D = *DIt;
336 if (D->getSourceRange().isInvalid())
337 continue;
338
339 if (isInLexicalContext(D, CurDC))
340 continue;
341
342 CurDC = dyn_cast<DeclContext>(D);
343
344 if (TagDecl *TD = dyn_cast<TagDecl>(D))
345 if (!TD->isFreeStanding())
346 continue;
347
348 RangeComparisonResult CompRes = RangeCompare(SM, D->getSourceRange(),Range);
349 if (CompRes == RangeBefore)
350 continue;
351 if (CompRes == RangeAfter)
352 break;
353
354 assert(CompRes == RangeOverlap);
355 VisitedAtLeastOnce = true;
356
357 if (isa<ObjCContainerDecl>(D)) {
358 FileDI_current = &DIt;
359 FileDE_current = DE;
360 } else {
Craig Topper69186e72014-06-08 08:38:04 +0000361 FileDI_current = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +0000362 }
363
364 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000365 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000366 }
367
368 if (VisitedAtLeastOnce)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000369 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000370
371 // No Decls overlapped with the range. Move up the lexical context until there
372 // is a context that contains the range or we reach the translation unit
373 // level.
374 DeclContext *DC = DIt == Decls.begin() ? (*DIt)->getLexicalDeclContext()
375 : (*(DIt-1))->getLexicalDeclContext();
376
377 while (DC && !DC->isTranslationUnit()) {
378 Decl *D = cast<Decl>(DC);
379 SourceRange CurDeclRange = D->getSourceRange();
380 if (CurDeclRange.isInvalid())
381 break;
382
383 if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000384 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
385 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000386 }
387
388 DC = D->getLexicalDeclContext();
389 }
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000390
391 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000392}
393
394bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
395 if (!AU->getPreprocessor().getPreprocessingRecord())
396 return false;
397
398 PreprocessingRecord &PPRec
399 = *AU->getPreprocessor().getPreprocessingRecord();
400 SourceManager &SM = AU->getSourceManager();
401
402 if (RegionOfInterest.isValid()) {
403 SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
404 SourceLocation B = MappedRange.getBegin();
405 SourceLocation E = MappedRange.getEnd();
406
407 if (AU->isInPreambleFileID(B)) {
408 if (SM.isLoadedSourceLocation(E))
409 return visitPreprocessedEntitiesInRange(SourceRange(B, E),
410 PPRec, *this);
411
412 // Beginning of range lies in the preamble but it also extends beyond
413 // it into the main file. Split the range into 2 parts, one covering
414 // the preamble and another covering the main file. This allows subsequent
415 // calls to visitPreprocessedEntitiesInRange to accept a source range that
416 // lies in the same FileID, allowing it to skip preprocessed entities that
417 // do not come from the same FileID.
418 bool breaked =
419 visitPreprocessedEntitiesInRange(
420 SourceRange(B, AU->getEndOfPreambleFileID()),
421 PPRec, *this);
422 if (breaked) return true;
423 return visitPreprocessedEntitiesInRange(
424 SourceRange(AU->getStartOfMainFileID(), E),
425 PPRec, *this);
426 }
427
428 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
429 }
430
431 bool OnlyLocalDecls
432 = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
433
434 if (OnlyLocalDecls)
435 return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
436 PPRec);
437
438 return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
439}
440
441template<typename InputIterator>
442bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
443 InputIterator Last,
444 PreprocessingRecord &PPRec,
445 FileID FID) {
446 for (; First != Last; ++First) {
447 if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
448 continue;
449
450 PreprocessedEntity *PPE = *First;
Argyrios Kyrtzidis1030f262013-05-07 20:37:17 +0000451 if (!PPE)
452 continue;
453
Guy Benyei11169dd2012-12-18 14:30:41 +0000454 if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
455 if (Visit(MakeMacroExpansionCursor(ME, TU)))
456 return true;
Richard Smith66a81862015-05-04 02:25:31 +0000457
Guy Benyei11169dd2012-12-18 14:30:41 +0000458 continue;
459 }
Richard Smith66a81862015-05-04 02:25:31 +0000460
461 if (MacroDefinitionRecord *MD = dyn_cast<MacroDefinitionRecord>(PPE)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000462 if (Visit(MakeMacroDefinitionCursor(MD, TU)))
463 return true;
Richard Smith66a81862015-05-04 02:25:31 +0000464
Guy Benyei11169dd2012-12-18 14:30:41 +0000465 continue;
466 }
467
468 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
469 if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
470 return true;
471
472 continue;
473 }
474 }
475
476 return false;
477}
478
479/// \brief Visit the children of the given cursor.
480///
481/// \returns true if the visitation should be aborted, false if it
482/// should continue.
483bool CursorVisitor::VisitChildren(CXCursor Cursor) {
484 if (clang_isReference(Cursor.kind) &&
485 Cursor.kind != CXCursor_CXXBaseSpecifier) {
486 // By definition, references have no children.
487 return false;
488 }
489
490 // Set the Parent field to Cursor, then back to its old value once we're
491 // done.
492 SetParentRAII SetParent(Parent, StmtParent, Cursor);
493
494 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000495 Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +0000496 if (!D)
497 return false;
498
499 return VisitAttributes(D) || Visit(D);
500 }
501
502 if (clang_isStatement(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000503 if (const Stmt *S = getCursorStmt(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000504 return Visit(S);
505
506 return false;
507 }
508
509 if (clang_isExpression(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000510 if (const Expr *E = getCursorExpr(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000511 return Visit(E);
512
513 return false;
514 }
515
516 if (clang_isTranslationUnit(Cursor.kind)) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000517 CXTranslationUnit TU = getCursorTU(Cursor);
518 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000519
520 int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
521 for (unsigned I = 0; I != 2; ++I) {
522 if (VisitOrder[I]) {
523 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
524 RegionOfInterest.isInvalid()) {
525 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
526 TLEnd = CXXUnit->top_level_end();
527 TL != TLEnd; ++TL) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000528 if (Visit(MakeCXCursor(*TL, TU, RegionOfInterest), true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000529 return true;
530 }
531 } else if (VisitDeclContext(
532 CXXUnit->getASTContext().getTranslationUnitDecl()))
533 return true;
534 continue;
535 }
536
537 // Walk the preprocessing record.
538 if (CXXUnit->getPreprocessor().getPreprocessingRecord())
539 visitPreprocessedEntitiesInRegion();
540 }
541
542 return false;
543 }
544
545 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000546 if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000547 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
548 return Visit(BaseTSInfo->getTypeLoc());
549 }
550 }
551 }
552
553 if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +0000554 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +0000555 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
Richard Smithb1f9a282013-10-31 01:56:18 +0000556 if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())
Richard Smithb87c4652013-10-31 21:23:20 +0000557 return Visit(cxcursor::MakeCursorObjCClassRef(
558 ObjT->getInterface(),
559 A->getInterfaceLoc()->getTypeLoc().getLocStart(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +0000560 }
561
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000562 // If pointing inside a macro definition, check if the token is an identifier
563 // that was ever defined as a macro. In such a case, create a "pseudo" macro
564 // expansion cursor for that token.
565 SourceLocation BeginLoc = RegionOfInterest.getBegin();
566 if (Cursor.kind == CXCursor_MacroDefinition &&
567 BeginLoc == RegionOfInterest.getEnd()) {
568 SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000569 const MacroInfo *MI =
570 getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
Richard Smith66a81862015-05-04 02:25:31 +0000571 if (MacroDefinitionRecord *MacroDef =
572 checkForMacroInMacroDefinition(MI, Loc, TU))
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000573 return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
574 }
575
Guy Benyei11169dd2012-12-18 14:30:41 +0000576 // Nothing to visit at the moment.
577 return false;
578}
579
580bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
581 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
582 if (Visit(TSInfo->getTypeLoc()))
583 return true;
584
585 if (Stmt *Body = B->getBody())
586 return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
587
588 return false;
589}
590
Ted Kremenek03325582013-02-21 01:29:01 +0000591Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000592 if (RegionOfInterest.isValid()) {
593 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
594 if (Range.isInvalid())
David Blaikie7a30dc52013-02-21 01:47:18 +0000595 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000596
597 switch (CompareRegionOfInterest(Range)) {
598 case RangeBefore:
599 // This declaration comes before the region of interest; skip it.
David Blaikie7a30dc52013-02-21 01:47:18 +0000600 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000601
602 case RangeAfter:
603 // This declaration comes after the region of interest; we're done.
604 return false;
605
606 case RangeOverlap:
607 // This declaration overlaps the region of interest; visit it.
608 break;
609 }
610 }
611 return true;
612}
613
614bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
615 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
616
617 // FIXME: Eventually remove. This part of a hack to support proper
618 // iteration over all Decls contained lexically within an ObjC container.
619 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
620 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
621
622 for ( ; I != E; ++I) {
623 Decl *D = *I;
624 if (D->getLexicalDeclContext() != DC)
625 continue;
626 CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
627
628 // Ignore synthesized ivars here, otherwise if we have something like:
629 // @synthesize prop = _prop;
630 // and '_prop' is not declared, we will encounter a '_prop' ivar before
631 // encountering the 'prop' synthesize declaration and we will think that
632 // we passed the region-of-interest.
633 if (ObjCIvarDecl *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
634 if (ivarD->getSynthesize())
635 continue;
636 }
637
638 // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
639 // declarations is a mismatch with the compiler semantics.
640 if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
641 ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
642 if (!ID->isThisDeclarationADefinition())
643 Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
644
645 } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
646 ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
647 if (!PD->isThisDeclarationADefinition())
648 Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
649 }
650
Ted Kremenek03325582013-02-21 01:29:01 +0000651 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000652 if (!V.hasValue())
653 continue;
654 if (!V.getValue())
655 return false;
656 if (Visit(Cursor, true))
657 return true;
658 }
659 return false;
660}
661
662bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
663 llvm_unreachable("Translation units are visited directly by Visit()");
664}
665
666bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
667 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
668 return Visit(TSInfo->getTypeLoc());
669
670 return false;
671}
672
673bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
674 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
675 return Visit(TSInfo->getTypeLoc());
676
677 return false;
678}
679
680bool CursorVisitor::VisitTagDecl(TagDecl *D) {
681 return VisitDeclContext(D);
682}
683
684bool CursorVisitor::VisitClassTemplateSpecializationDecl(
685 ClassTemplateSpecializationDecl *D) {
686 bool ShouldVisitBody = false;
687 switch (D->getSpecializationKind()) {
688 case TSK_Undeclared:
689 case TSK_ImplicitInstantiation:
690 // Nothing to visit
691 return false;
692
693 case TSK_ExplicitInstantiationDeclaration:
694 case TSK_ExplicitInstantiationDefinition:
695 break;
696
697 case TSK_ExplicitSpecialization:
698 ShouldVisitBody = true;
699 break;
700 }
701
702 // Visit the template arguments used in the specialization.
703 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
704 TypeLoc TL = SpecType->getTypeLoc();
David Blaikie6adc78e2013-02-18 22:06:02 +0000705 if (TemplateSpecializationTypeLoc TSTLoc =
706 TL.getAs<TemplateSpecializationTypeLoc>()) {
707 for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
708 if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000709 return true;
710 }
711 }
712
713 if (ShouldVisitBody && VisitCXXRecordDecl(D))
714 return true;
715
716 return false;
717}
718
719bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
720 ClassTemplatePartialSpecializationDecl *D) {
721 // FIXME: Visit the "outer" template parameter lists on the TagDecl
722 // before visiting these template parameters.
723 if (VisitTemplateParameters(D->getTemplateParameters()))
724 return true;
725
726 // Visit the partial specialization arguments.
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000727 const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
728 const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
729 for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
Guy Benyei11169dd2012-12-18 14:30:41 +0000730 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
731 return true;
732
733 return VisitCXXRecordDecl(D);
734}
735
736bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
737 // Visit the default argument.
738 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
739 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
740 if (Visit(DefArg->getTypeLoc()))
741 return true;
742
743 return false;
744}
745
746bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
747 if (Expr *Init = D->getInitExpr())
748 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
749 return false;
750}
751
752bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000753 unsigned NumParamList = DD->getNumTemplateParameterLists();
754 for (unsigned i = 0; i < NumParamList; i++) {
755 TemplateParameterList* Params = DD->getTemplateParameterList(i);
756 if (VisitTemplateParameters(Params))
757 return true;
758 }
759
Guy Benyei11169dd2012-12-18 14:30:41 +0000760 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
761 if (Visit(TSInfo->getTypeLoc()))
762 return true;
763
764 // Visit the nested-name-specifier, if present.
765 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
766 if (VisitNestedNameSpecifierLoc(QualifierLoc))
767 return true;
768
769 return false;
770}
771
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000772/// \brief Compare two base or member initializers based on their source order.
773static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
774 CXXCtorInitializer *const *Y) {
775 return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
776}
777
Guy Benyei11169dd2012-12-18 14:30:41 +0000778bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000779 unsigned NumParamList = ND->getNumTemplateParameterLists();
780 for (unsigned i = 0; i < NumParamList; i++) {
781 TemplateParameterList* Params = ND->getTemplateParameterList(i);
782 if (VisitTemplateParameters(Params))
783 return true;
784 }
785
Guy Benyei11169dd2012-12-18 14:30:41 +0000786 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
787 // Visit the function declaration's syntactic components in the order
788 // written. This requires a bit of work.
789 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
David Blaikie6adc78e2013-02-18 22:06:02 +0000790 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Guy Benyei11169dd2012-12-18 14:30:41 +0000791
792 // If we have a function declared directly (without the use of a typedef),
793 // visit just the return type. Otherwise, just visit the function's type
794 // now.
Alp Toker42a16a62014-01-25 23:51:36 +0000795 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getReturnLoc())) ||
Guy Benyei11169dd2012-12-18 14:30:41 +0000796 (!FTL && Visit(TL)))
797 return true;
798
799 // Visit the nested-name-specifier, if present.
800 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
801 if (VisitNestedNameSpecifierLoc(QualifierLoc))
802 return true;
803
804 // Visit the declaration name.
Argyrios Kyrtzidis4a4d2b42014-02-09 08:13:47 +0000805 if (!isa<CXXDestructorDecl>(ND))
806 if (VisitDeclarationNameInfo(ND->getNameInfo()))
807 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +0000808
809 // FIXME: Visit explicitly-specified template arguments!
810
811 // Visit the function parameters, if we have a function type.
David Blaikie6adc78e2013-02-18 22:06:02 +0000812 if (FTL && VisitFunctionTypeLoc(FTL, true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000813 return true;
814
Bill Wendling44426052012-12-20 19:22:21 +0000815 // FIXME: Attributes?
Guy Benyei11169dd2012-12-18 14:30:41 +0000816 }
817
818 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
819 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
820 // Find the initializers that were written in the source.
821 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
Aaron Ballman0ad78302014-03-13 17:34:31 +0000822 for (auto *I : Constructor->inits()) {
823 if (!I->isWritten())
Guy Benyei11169dd2012-12-18 14:30:41 +0000824 continue;
825
Aaron Ballman0ad78302014-03-13 17:34:31 +0000826 WrittenInits.push_back(I);
Guy Benyei11169dd2012-12-18 14:30:41 +0000827 }
828
829 // Sort the initializers in source order
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000830 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
831 &CompareCXXCtorInitializers);
832
Guy Benyei11169dd2012-12-18 14:30:41 +0000833 // Visit the initializers in source order
834 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
835 CXXCtorInitializer *Init = WrittenInits[I];
836 if (Init->isAnyMemberInitializer()) {
837 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
838 Init->getMemberLocation(), TU)))
839 return true;
840 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
841 if (Visit(TInfo->getTypeLoc()))
842 return true;
843 }
844
845 // Visit the initializer value.
846 if (Expr *Initializer = Init->getInit())
847 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
848 return true;
849 }
850 }
851
852 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
853 return true;
854 }
855
856 return false;
857}
858
859bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
860 if (VisitDeclaratorDecl(D))
861 return true;
862
863 if (Expr *BitWidth = D->getBitWidth())
864 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
865
866 return false;
867}
868
869bool CursorVisitor::VisitVarDecl(VarDecl *D) {
870 if (VisitDeclaratorDecl(D))
871 return true;
872
873 if (Expr *Init = D->getInit())
874 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
875
876 return false;
877}
878
879bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
880 if (VisitDeclaratorDecl(D))
881 return true;
882
883 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
884 if (Expr *DefArg = D->getDefaultArgument())
885 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
886
887 return false;
888}
889
890bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
891 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
892 // before visiting these template parameters.
893 if (VisitTemplateParameters(D->getTemplateParameters()))
894 return true;
895
896 return VisitFunctionDecl(D->getTemplatedDecl());
897}
898
899bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
900 // FIXME: Visit the "outer" template parameter lists on the TagDecl
901 // before visiting these template parameters.
902 if (VisitTemplateParameters(D->getTemplateParameters()))
903 return true;
904
905 return VisitCXXRecordDecl(D->getTemplatedDecl());
906}
907
908bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
909 if (VisitTemplateParameters(D->getTemplateParameters()))
910 return true;
911
912 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
913 VisitTemplateArgumentLoc(D->getDefaultArgument()))
914 return true;
915
916 return false;
917}
918
Douglas Gregor9bda6cf2015-07-07 03:58:14 +0000919bool CursorVisitor::VisitObjCTypeParamDecl(ObjCTypeParamDecl *D) {
920 // Visit the bound, if it's explicit.
921 if (D->hasExplicitBound()) {
922 if (auto TInfo = D->getTypeSourceInfo()) {
923 if (Visit(TInfo->getTypeLoc()))
924 return true;
925 }
926 }
927
928 return false;
929}
930
Guy Benyei11169dd2012-12-18 14:30:41 +0000931bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Alp Toker314cc812014-01-25 16:55:45 +0000932 if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
Guy Benyei11169dd2012-12-18 14:30:41 +0000933 if (Visit(TSInfo->getTypeLoc()))
934 return true;
935
Aaron Ballman43b68be2014-03-07 17:50:17 +0000936 for (const auto *P : ND->params()) {
937 if (Visit(MakeCXCursor(P, TU, RegionOfInterest)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000938 return true;
939 }
940
941 if (ND->isThisDeclarationADefinition() &&
942 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
943 return true;
944
945 return false;
946}
947
948template <typename DeclIt>
949static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
950 SourceManager &SM, SourceLocation EndLoc,
951 SmallVectorImpl<Decl *> &Decls) {
952 DeclIt next = *DI_current;
953 while (++next != DE_current) {
954 Decl *D_next = *next;
955 if (!D_next)
956 break;
957 SourceLocation L = D_next->getLocStart();
958 if (!L.isValid())
959 break;
960 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
961 *DI_current = next;
962 Decls.push_back(D_next);
963 continue;
964 }
965 break;
966 }
967}
968
Guy Benyei11169dd2012-12-18 14:30:41 +0000969bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
970 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
971 // an @implementation can lexically contain Decls that are not properly
972 // nested in the AST. When we identify such cases, we need to retrofit
973 // this nesting here.
974 if (!DI_current && !FileDI_current)
975 return VisitDeclContext(D);
976
977 // Scan the Decls that immediately come after the container
978 // in the current DeclContext. If any fall within the
979 // container's lexical region, stash them into a vector
980 // for later processing.
981 SmallVector<Decl *, 24> DeclsInContainer;
982 SourceLocation EndLoc = D->getSourceRange().getEnd();
983 SourceManager &SM = AU->getSourceManager();
984 if (EndLoc.isValid()) {
985 if (DI_current) {
986 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
987 DeclsInContainer);
988 } else {
989 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
990 DeclsInContainer);
991 }
992 }
993
994 // The common case.
995 if (DeclsInContainer.empty())
996 return VisitDeclContext(D);
997
998 // Get all the Decls in the DeclContext, and sort them with the
999 // additional ones we've collected. Then visit them.
Aaron Ballman629afae2014-03-07 19:56:05 +00001000 for (auto *SubDecl : D->decls()) {
1001 if (!SubDecl || SubDecl->getLexicalDeclContext() != D ||
1002 SubDecl->getLocStart().isInvalid())
Guy Benyei11169dd2012-12-18 14:30:41 +00001003 continue;
Aaron Ballman629afae2014-03-07 19:56:05 +00001004 DeclsInContainer.push_back(SubDecl);
Guy Benyei11169dd2012-12-18 14:30:41 +00001005 }
1006
1007 // Now sort the Decls so that they appear in lexical order.
1008 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
Benjamin Kramerbbdd7642014-03-01 14:48:57 +00001009 [&SM](Decl *A, Decl *B) {
1010 SourceLocation L_A = A->getLocStart();
1011 SourceLocation L_B = B->getLocStart();
1012 assert(L_A.isValid() && L_B.isValid());
1013 return SM.isBeforeInTranslationUnit(L_A, L_B);
1014 });
Guy Benyei11169dd2012-12-18 14:30:41 +00001015
1016 // Now visit the decls.
1017 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
1018 E = DeclsInContainer.end(); I != E; ++I) {
1019 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek03325582013-02-21 01:29:01 +00001020 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00001021 if (!V.hasValue())
1022 continue;
1023 if (!V.getValue())
1024 return false;
1025 if (Visit(Cursor, true))
1026 return true;
1027 }
1028 return false;
1029}
1030
1031bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1032 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1033 TU)))
1034 return true;
1035
Douglas Gregore9d95f12015-07-07 03:57:35 +00001036 if (VisitObjCTypeParamList(ND->getTypeParamList()))
1037 return true;
1038
Guy Benyei11169dd2012-12-18 14:30:41 +00001039 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1040 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1041 E = ND->protocol_end(); I != E; ++I, ++PL)
1042 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1043 return true;
1044
1045 return VisitObjCContainerDecl(ND);
1046}
1047
1048bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1049 if (!PID->isThisDeclarationADefinition())
1050 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1051
1052 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1053 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1054 E = PID->protocol_end(); I != E; ++I, ++PL)
1055 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1056 return true;
1057
1058 return VisitObjCContainerDecl(PID);
1059}
1060
1061bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1062 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1063 return true;
1064
1065 // FIXME: This implements a workaround with @property declarations also being
1066 // installed in the DeclContext for the @interface. Eventually this code
1067 // should be removed.
1068 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1069 if (!CDecl || !CDecl->IsClassExtension())
1070 return false;
1071
1072 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1073 if (!ID)
1074 return false;
1075
1076 IdentifierInfo *PropertyId = PD->getIdentifier();
1077 ObjCPropertyDecl *prevDecl =
1078 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1079
1080 if (!prevDecl)
1081 return false;
1082
1083 // Visit synthesized methods since they will be skipped when visiting
1084 // the @interface.
1085 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1086 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1087 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1088 return true;
1089
1090 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1091 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1092 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1093 return true;
1094
1095 return false;
1096}
1097
Douglas Gregore9d95f12015-07-07 03:57:35 +00001098bool CursorVisitor::VisitObjCTypeParamList(ObjCTypeParamList *typeParamList) {
1099 if (!typeParamList)
1100 return false;
1101
1102 for (auto *typeParam : *typeParamList) {
1103 // Visit the type parameter.
1104 if (Visit(MakeCXCursor(typeParam, TU, RegionOfInterest)))
1105 return true;
Douglas Gregore9d95f12015-07-07 03:57:35 +00001106 }
1107
1108 return false;
1109}
1110
Guy Benyei11169dd2012-12-18 14:30:41 +00001111bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1112 if (!D->isThisDeclarationADefinition()) {
1113 // Forward declaration is treated like a reference.
1114 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1115 }
1116
Douglas Gregore9d95f12015-07-07 03:57:35 +00001117 // Objective-C type parameters.
1118 if (VisitObjCTypeParamList(D->getTypeParamListAsWritten()))
1119 return true;
1120
Guy Benyei11169dd2012-12-18 14:30:41 +00001121 // Issue callbacks for super class.
1122 if (D->getSuperClass() &&
1123 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1124 D->getSuperClassLoc(),
1125 TU)))
1126 return true;
1127
Douglas Gregore9d95f12015-07-07 03:57:35 +00001128 if (TypeSourceInfo *SuperClassTInfo = D->getSuperClassTInfo())
1129 if (Visit(SuperClassTInfo->getTypeLoc()))
1130 return true;
1131
Guy Benyei11169dd2012-12-18 14:30:41 +00001132 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1133 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1134 E = D->protocol_end(); I != E; ++I, ++PL)
1135 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1136 return true;
1137
1138 return VisitObjCContainerDecl(D);
1139}
1140
1141bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1142 return VisitObjCContainerDecl(D);
1143}
1144
1145bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1146 // 'ID' could be null when dealing with invalid code.
1147 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1148 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1149 return true;
1150
1151 return VisitObjCImplDecl(D);
1152}
1153
1154bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1155#if 0
1156 // Issue callbacks for super class.
1157 // FIXME: No source location information!
1158 if (D->getSuperClass() &&
1159 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1160 D->getSuperClassLoc(),
1161 TU)))
1162 return true;
1163#endif
1164
1165 return VisitObjCImplDecl(D);
1166}
1167
1168bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1169 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1170 if (PD->isIvarNameSpecified())
1171 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1172
1173 return false;
1174}
1175
1176bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1177 return VisitDeclContext(D);
1178}
1179
1180bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1181 // Visit nested-name-specifier.
1182 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1183 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1184 return true;
1185
1186 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1187 D->getTargetNameLoc(), TU));
1188}
1189
1190bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1191 // Visit nested-name-specifier.
1192 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1193 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1194 return true;
1195 }
1196
1197 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1198 return true;
1199
1200 return VisitDeclarationNameInfo(D->getNameInfo());
1201}
1202
1203bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1204 // Visit nested-name-specifier.
1205 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1206 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1207 return true;
1208
1209 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1210 D->getIdentLocation(), TU));
1211}
1212
1213bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1214 // Visit nested-name-specifier.
1215 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1216 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1217 return true;
1218 }
1219
1220 return VisitDeclarationNameInfo(D->getNameInfo());
1221}
1222
1223bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1224 UnresolvedUsingTypenameDecl *D) {
1225 // Visit nested-name-specifier.
1226 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1227 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1228 return true;
1229
1230 return false;
1231}
1232
1233bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1234 switch (Name.getName().getNameKind()) {
1235 case clang::DeclarationName::Identifier:
1236 case clang::DeclarationName::CXXLiteralOperatorName:
1237 case clang::DeclarationName::CXXOperatorName:
1238 case clang::DeclarationName::CXXUsingDirective:
1239 return false;
1240
1241 case clang::DeclarationName::CXXConstructorName:
1242 case clang::DeclarationName::CXXDestructorName:
1243 case clang::DeclarationName::CXXConversionFunctionName:
1244 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1245 return Visit(TSInfo->getTypeLoc());
1246 return false;
1247
1248 case clang::DeclarationName::ObjCZeroArgSelector:
1249 case clang::DeclarationName::ObjCOneArgSelector:
1250 case clang::DeclarationName::ObjCMultiArgSelector:
1251 // FIXME: Per-identifier location info?
1252 return false;
1253 }
1254
1255 llvm_unreachable("Invalid DeclarationName::Kind!");
1256}
1257
1258bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1259 SourceRange Range) {
1260 // FIXME: This whole routine is a hack to work around the lack of proper
1261 // source information in nested-name-specifiers (PR5791). Since we do have
1262 // a beginning source location, we can visit the first component of the
1263 // nested-name-specifier, if it's a single-token component.
1264 if (!NNS)
1265 return false;
1266
1267 // Get the first component in the nested-name-specifier.
1268 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1269 NNS = Prefix;
1270
1271 switch (NNS->getKind()) {
1272 case NestedNameSpecifier::Namespace:
1273 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1274 TU));
1275
1276 case NestedNameSpecifier::NamespaceAlias:
1277 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1278 Range.getBegin(), TU));
1279
1280 case NestedNameSpecifier::TypeSpec: {
1281 // If the type has a form where we know that the beginning of the source
1282 // range matches up with a reference cursor. Visit the appropriate reference
1283 // cursor.
1284 const Type *T = NNS->getAsType();
1285 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1286 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1287 if (const TagType *Tag = dyn_cast<TagType>(T))
1288 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1289 if (const TemplateSpecializationType *TST
1290 = dyn_cast<TemplateSpecializationType>(T))
1291 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1292 break;
1293 }
1294
1295 case NestedNameSpecifier::TypeSpecWithTemplate:
1296 case NestedNameSpecifier::Global:
1297 case NestedNameSpecifier::Identifier:
Nikola Smiljanic67860242014-09-26 00:28:20 +00001298 case NestedNameSpecifier::Super:
Guy Benyei11169dd2012-12-18 14:30:41 +00001299 break;
1300 }
1301
1302 return false;
1303}
1304
1305bool
1306CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1307 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1308 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1309 Qualifiers.push_back(Qualifier);
1310
1311 while (!Qualifiers.empty()) {
1312 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1313 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1314 switch (NNS->getKind()) {
1315 case NestedNameSpecifier::Namespace:
1316 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1317 Q.getLocalBeginLoc(),
1318 TU)))
1319 return true;
1320
1321 break;
1322
1323 case NestedNameSpecifier::NamespaceAlias:
1324 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1325 Q.getLocalBeginLoc(),
1326 TU)))
1327 return true;
1328
1329 break;
1330
1331 case NestedNameSpecifier::TypeSpec:
1332 case NestedNameSpecifier::TypeSpecWithTemplate:
1333 if (Visit(Q.getTypeLoc()))
1334 return true;
1335
1336 break;
1337
1338 case NestedNameSpecifier::Global:
1339 case NestedNameSpecifier::Identifier:
Nikola Smiljanic67860242014-09-26 00:28:20 +00001340 case NestedNameSpecifier::Super:
Guy Benyei11169dd2012-12-18 14:30:41 +00001341 break;
1342 }
1343 }
1344
1345 return false;
1346}
1347
1348bool CursorVisitor::VisitTemplateParameters(
1349 const TemplateParameterList *Params) {
1350 if (!Params)
1351 return false;
1352
1353 for (TemplateParameterList::const_iterator P = Params->begin(),
1354 PEnd = Params->end();
1355 P != PEnd; ++P) {
1356 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1357 return true;
1358 }
1359
1360 return false;
1361}
1362
1363bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1364 switch (Name.getKind()) {
1365 case TemplateName::Template:
1366 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1367
1368 case TemplateName::OverloadedTemplate:
1369 // Visit the overloaded template set.
1370 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1371 return true;
1372
1373 return false;
1374
1375 case TemplateName::DependentTemplate:
1376 // FIXME: Visit nested-name-specifier.
1377 return false;
1378
1379 case TemplateName::QualifiedTemplate:
1380 // FIXME: Visit nested-name-specifier.
1381 return Visit(MakeCursorTemplateRef(
1382 Name.getAsQualifiedTemplateName()->getDecl(),
1383 Loc, TU));
1384
1385 case TemplateName::SubstTemplateTemplateParm:
1386 return Visit(MakeCursorTemplateRef(
1387 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1388 Loc, TU));
1389
1390 case TemplateName::SubstTemplateTemplateParmPack:
1391 return Visit(MakeCursorTemplateRef(
1392 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1393 Loc, TU));
1394 }
1395
1396 llvm_unreachable("Invalid TemplateName::Kind!");
1397}
1398
1399bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1400 switch (TAL.getArgument().getKind()) {
1401 case TemplateArgument::Null:
1402 case TemplateArgument::Integral:
1403 case TemplateArgument::Pack:
1404 return false;
1405
1406 case TemplateArgument::Type:
1407 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1408 return Visit(TSInfo->getTypeLoc());
1409 return false;
1410
1411 case TemplateArgument::Declaration:
1412 if (Expr *E = TAL.getSourceDeclExpression())
1413 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1414 return false;
1415
1416 case TemplateArgument::NullPtr:
1417 if (Expr *E = TAL.getSourceNullPtrExpression())
1418 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1419 return false;
1420
1421 case TemplateArgument::Expression:
1422 if (Expr *E = TAL.getSourceExpression())
1423 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1424 return false;
1425
1426 case TemplateArgument::Template:
1427 case TemplateArgument::TemplateExpansion:
1428 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1429 return true;
1430
1431 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1432 TAL.getTemplateNameLoc());
1433 }
1434
1435 llvm_unreachable("Invalid TemplateArgument::Kind!");
1436}
1437
1438bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1439 return VisitDeclContext(D);
1440}
1441
1442bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1443 return Visit(TL.getUnqualifiedLoc());
1444}
1445
1446bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1447 ASTContext &Context = AU->getASTContext();
1448
1449 // Some builtin types (such as Objective-C's "id", "sel", and
1450 // "Class") have associated declarations. Create cursors for those.
1451 QualType VisitType;
1452 switch (TL.getTypePtr()->getKind()) {
1453
1454 case BuiltinType::Void:
1455 case BuiltinType::NullPtr:
1456 case BuiltinType::Dependent:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001457 case BuiltinType::OCLImage1d:
1458 case BuiltinType::OCLImage1dArray:
1459 case BuiltinType::OCLImage1dBuffer:
1460 case BuiltinType::OCLImage2d:
1461 case BuiltinType::OCLImage2dArray:
1462 case BuiltinType::OCLImage3d:
NAKAMURA Takumi288c42e2013-02-07 12:47:42 +00001463 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +00001464 case BuiltinType::OCLEvent:
Guy Benyei11169dd2012-12-18 14:30:41 +00001465#define BUILTIN_TYPE(Id, SingletonId)
1466#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1467#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1468#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1469#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1470#include "clang/AST/BuiltinTypes.def"
1471 break;
1472
1473 case BuiltinType::ObjCId:
1474 VisitType = Context.getObjCIdType();
1475 break;
1476
1477 case BuiltinType::ObjCClass:
1478 VisitType = Context.getObjCClassType();
1479 break;
1480
1481 case BuiltinType::ObjCSel:
1482 VisitType = Context.getObjCSelType();
1483 break;
1484 }
1485
1486 if (!VisitType.isNull()) {
1487 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1488 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1489 TU));
1490 }
1491
1492 return false;
1493}
1494
1495bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1496 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1497}
1498
1499bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1500 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1501}
1502
1503bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1504 if (TL.isDefinition())
1505 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1506
1507 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1508}
1509
1510bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1511 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1512}
1513
1514bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1515 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1516 return true;
1517
1518 return false;
1519}
1520
1521bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1522 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1523 return true;
1524
Douglas Gregore9d95f12015-07-07 03:57:35 +00001525 for (unsigned I = 0, N = TL.getNumTypeArgs(); I != N; ++I) {
1526 if (Visit(TL.getTypeArgTInfo(I)->getTypeLoc()))
1527 return true;
1528 }
1529
Guy Benyei11169dd2012-12-18 14:30:41 +00001530 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1531 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1532 TU)))
1533 return true;
1534 }
1535
1536 return false;
1537}
1538
1539bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1540 return Visit(TL.getPointeeLoc());
1541}
1542
1543bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1544 return Visit(TL.getInnerLoc());
1545}
1546
1547bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1548 return Visit(TL.getPointeeLoc());
1549}
1550
1551bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1552 return Visit(TL.getPointeeLoc());
1553}
1554
1555bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1556 return Visit(TL.getPointeeLoc());
1557}
1558
1559bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1560 return Visit(TL.getPointeeLoc());
1561}
1562
1563bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1564 return Visit(TL.getPointeeLoc());
1565}
1566
1567bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1568 return Visit(TL.getModifiedLoc());
1569}
1570
1571bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1572 bool SkipResultType) {
Alp Toker42a16a62014-01-25 23:51:36 +00001573 if (!SkipResultType && Visit(TL.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001574 return true;
1575
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00001576 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1577 if (Decl *D = TL.getParam(I))
Guy Benyei11169dd2012-12-18 14:30:41 +00001578 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1579 return true;
1580
1581 return false;
1582}
1583
1584bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1585 if (Visit(TL.getElementLoc()))
1586 return true;
1587
1588 if (Expr *Size = TL.getSizeExpr())
1589 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1590
1591 return false;
1592}
1593
Reid Kleckner8a365022013-06-24 17:51:48 +00001594bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1595 return Visit(TL.getOriginalLoc());
1596}
1597
Reid Kleckner0503a872013-12-05 01:23:43 +00001598bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1599 return Visit(TL.getOriginalLoc());
1600}
1601
Guy Benyei11169dd2012-12-18 14:30:41 +00001602bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1603 TemplateSpecializationTypeLoc TL) {
1604 // Visit the template name.
1605 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1606 TL.getTemplateNameLoc()))
1607 return true;
1608
1609 // Visit the template arguments.
1610 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1611 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1612 return true;
1613
1614 return false;
1615}
1616
1617bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1618 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1619}
1620
1621bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1622 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1623 return Visit(TSInfo->getTypeLoc());
1624
1625 return false;
1626}
1627
1628bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1629 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1630 return Visit(TSInfo->getTypeLoc());
1631
1632 return false;
1633}
1634
1635bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1636 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1637 return true;
1638
1639 return false;
1640}
1641
1642bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1643 DependentTemplateSpecializationTypeLoc TL) {
1644 // Visit the nested-name-specifier, if there is one.
1645 if (TL.getQualifierLoc() &&
1646 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1647 return true;
1648
1649 // Visit the template arguments.
1650 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1651 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1652 return true;
1653
1654 return false;
1655}
1656
1657bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1658 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1659 return true;
1660
1661 return Visit(TL.getNamedTypeLoc());
1662}
1663
1664bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1665 return Visit(TL.getPatternLoc());
1666}
1667
1668bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1669 if (Expr *E = TL.getUnderlyingExpr())
1670 return Visit(MakeCXCursor(E, StmtParent, TU));
1671
1672 return false;
1673}
1674
1675bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1676 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1677}
1678
1679bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1680 return Visit(TL.getValueLoc());
1681}
1682
1683#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1684bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1685 return Visit##PARENT##Loc(TL); \
1686}
1687
1688DEFAULT_TYPELOC_IMPL(Complex, Type)
1689DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1690DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1691DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1692DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1693DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1694DEFAULT_TYPELOC_IMPL(Vector, Type)
1695DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1696DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1697DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1698DEFAULT_TYPELOC_IMPL(Record, TagType)
1699DEFAULT_TYPELOC_IMPL(Enum, TagType)
1700DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1701DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1702DEFAULT_TYPELOC_IMPL(Auto, Type)
1703
1704bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1705 // Visit the nested-name-specifier, if present.
1706 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1707 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1708 return true;
1709
1710 if (D->isCompleteDefinition()) {
Aaron Ballman574705e2014-03-13 15:41:46 +00001711 for (const auto &I : D->bases()) {
1712 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001713 return true;
1714 }
1715 }
1716
1717 return VisitTagDecl(D);
1718}
1719
1720bool CursorVisitor::VisitAttributes(Decl *D) {
Aaron Ballmanb97112e2014-03-08 22:19:01 +00001721 for (const auto *I : D->attrs())
1722 if (Visit(MakeCXCursor(I, D, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001723 return true;
1724
1725 return false;
1726}
1727
1728//===----------------------------------------------------------------------===//
1729// Data-recursive visitor methods.
1730//===----------------------------------------------------------------------===//
1731
1732namespace {
1733#define DEF_JOB(NAME, DATA, KIND)\
1734class NAME : public VisitorJob {\
1735public:\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001736 NAME(const DATA *d, CXCursor parent) : \
1737 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei11169dd2012-12-18 14:30:41 +00001738 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001739 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei11169dd2012-12-18 14:30:41 +00001740};
1741
1742DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1743DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1744DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1745DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1746DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1747 ExplicitTemplateArgsVisitKind)
1748DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1749DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1750DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1751#undef DEF_JOB
1752
1753class DeclVisit : public VisitorJob {
1754public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001755 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei11169dd2012-12-18 14:30:41 +00001756 VisitorJob(parent, VisitorJob::DeclVisitKind,
Craig Topper69186e72014-06-08 08:38:04 +00001757 D, isFirst ? (void*) 1 : (void*) nullptr) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001758 static bool classof(const VisitorJob *VJ) {
1759 return VJ->getKind() == DeclVisitKind;
1760 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001761 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Dmitri Gribenkoe5423a72015-03-23 19:23:50 +00001762 bool isFirst() const { return data[1] != nullptr; }
Guy Benyei11169dd2012-12-18 14:30:41 +00001763};
1764class TypeLocVisit : public VisitorJob {
1765public:
1766 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1767 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1768 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1769
1770 static bool classof(const VisitorJob *VJ) {
1771 return VJ->getKind() == TypeLocVisitKind;
1772 }
1773
1774 TypeLoc get() const {
1775 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001776 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001777 }
1778};
1779
1780class LabelRefVisit : public VisitorJob {
1781public:
1782 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1783 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1784 labelLoc.getPtrEncoding()) {}
1785
1786 static bool classof(const VisitorJob *VJ) {
1787 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1788 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001789 const LabelDecl *get() const {
1790 return static_cast<const LabelDecl *>(data[0]);
1791 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001792 SourceLocation getLoc() const {
1793 return SourceLocation::getFromPtrEncoding(data[1]); }
1794};
1795
1796class NestedNameSpecifierLocVisit : public VisitorJob {
1797public:
1798 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1799 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1800 Qualifier.getNestedNameSpecifier(),
1801 Qualifier.getOpaqueData()) { }
1802
1803 static bool classof(const VisitorJob *VJ) {
1804 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1805 }
1806
1807 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001808 return NestedNameSpecifierLoc(
1809 const_cast<NestedNameSpecifier *>(
1810 static_cast<const NestedNameSpecifier *>(data[0])),
1811 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001812 }
1813};
1814
1815class DeclarationNameInfoVisit : public VisitorJob {
1816public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001817 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001818 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001819 static bool classof(const VisitorJob *VJ) {
1820 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1821 }
1822 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001823 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001824 switch (S->getStmtClass()) {
1825 default:
1826 llvm_unreachable("Unhandled Stmt");
1827 case clang::Stmt::MSDependentExistsStmtClass:
1828 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1829 case Stmt::CXXDependentScopeMemberExprClass:
1830 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1831 case Stmt::DependentScopeDeclRefExprClass:
1832 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001833 case Stmt::OMPCriticalDirectiveClass:
1834 return cast<OMPCriticalDirective>(S)->getDirectiveName();
Guy Benyei11169dd2012-12-18 14:30:41 +00001835 }
1836 }
1837};
1838class MemberRefVisit : public VisitorJob {
1839public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001840 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei11169dd2012-12-18 14:30:41 +00001841 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1842 L.getPtrEncoding()) {}
1843 static bool classof(const VisitorJob *VJ) {
1844 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1845 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001846 const FieldDecl *get() const {
1847 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001848 }
1849 SourceLocation getLoc() const {
1850 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1851 }
1852};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001853class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001854 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001855 VisitorWorkList &WL;
1856 CXCursor Parent;
1857public:
1858 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1859 : WL(wl), Parent(parent) {}
1860
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001861 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1862 void VisitBlockExpr(const BlockExpr *B);
1863 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1864 void VisitCompoundStmt(const CompoundStmt *S);
1865 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1866 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1867 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1868 void VisitCXXNewExpr(const CXXNewExpr *E);
1869 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1870 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1871 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1872 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1873 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1874 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1875 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1876 void VisitCXXCatchStmt(const CXXCatchStmt *S);
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00001877 void VisitCXXForRangeStmt(const CXXForRangeStmt *S);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001878 void VisitDeclRefExpr(const DeclRefExpr *D);
1879 void VisitDeclStmt(const DeclStmt *S);
1880 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1881 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1882 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1883 void VisitForStmt(const ForStmt *FS);
1884 void VisitGotoStmt(const GotoStmt *GS);
1885 void VisitIfStmt(const IfStmt *If);
1886 void VisitInitListExpr(const InitListExpr *IE);
1887 void VisitMemberExpr(const MemberExpr *M);
1888 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1889 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1890 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1891 void VisitOverloadExpr(const OverloadExpr *E);
1892 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1893 void VisitStmt(const Stmt *S);
1894 void VisitSwitchStmt(const SwitchStmt *S);
1895 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001896 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1897 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1898 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1899 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1900 void VisitVAArgExpr(const VAArgExpr *E);
1901 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1902 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1903 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1904 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001905 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
Alexander Musman3aaab662014-08-19 11:27:13 +00001906 void VisitOMPLoopDirective(const OMPLoopDirective *D);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001907 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00001908 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00001909 void VisitOMPForDirective(const OMPForDirective *D);
Alexander Musmanf82886e2014-09-18 05:12:34 +00001910 void VisitOMPForSimdDirective(const OMPForSimdDirective *D);
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00001911 void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
Alexey Bataev1e0498a2014-06-26 08:21:58 +00001912 void VisitOMPSectionDirective(const OMPSectionDirective *D);
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00001913 void VisitOMPSingleDirective(const OMPSingleDirective *D);
Alexander Musman80c22892014-07-17 08:54:58 +00001914 void VisitOMPMasterDirective(const OMPMasterDirective *D);
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001915 void VisitOMPCriticalDirective(const OMPCriticalDirective *D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00001916 void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
Alexander Musmane4e893b2014-09-23 09:33:00 +00001917 void VisitOMPParallelForSimdDirective(const OMPParallelForSimdDirective *D);
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00001918 void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective *D);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00001919 void VisitOMPTaskDirective(const OMPTaskDirective *D);
Alexey Bataev68446b72014-07-18 07:47:19 +00001920 void VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D);
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00001921 void VisitOMPBarrierDirective(const OMPBarrierDirective *D);
Alexey Bataev2df347a2014-07-18 10:17:07 +00001922 void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00001923 void VisitOMPTaskgroupDirective(const OMPTaskgroupDirective *D);
Alexey Bataev6d4ed052015-07-01 06:57:41 +00001924 void
1925 VisitOMPCancellationPointDirective(const OMPCancellationPointDirective *D);
Alexey Bataev80909872015-07-02 11:25:17 +00001926 void VisitOMPCancelDirective(const OMPCancelDirective *D);
Alexey Bataev6125da92014-07-21 11:26:11 +00001927 void VisitOMPFlushDirective(const OMPFlushDirective *D);
Alexey Bataev9fb6e642014-07-22 06:45:04 +00001928 void VisitOMPOrderedDirective(const OMPOrderedDirective *D);
Alexey Bataev0162e452014-07-22 10:10:35 +00001929 void VisitOMPAtomicDirective(const OMPAtomicDirective *D);
Alexey Bataev0bd520b2014-09-19 08:19:49 +00001930 void VisitOMPTargetDirective(const OMPTargetDirective *D);
Alexey Bataev13314bf2014-10-09 04:18:56 +00001931 void VisitOMPTeamsDirective(const OMPTeamsDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001932
Guy Benyei11169dd2012-12-18 14:30:41 +00001933private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001934 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001935 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1936 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001937 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1938 void AddStmt(const Stmt *S);
1939 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001940 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001941 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001942 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001943};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00001944} // end anonyous namespace
Guy Benyei11169dd2012-12-18 14:30:41 +00001945
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001946void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001947 // 'S' should always be non-null, since it comes from the
1948 // statement we are visiting.
1949 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1950}
1951
1952void
1953EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1954 if (Qualifier)
1955 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1956}
1957
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001958void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001959 if (S)
1960 WL.push_back(StmtVisit(S, Parent));
1961}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001962void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001963 if (D)
1964 WL.push_back(DeclVisit(D, Parent, isFirst));
1965}
1966void EnqueueVisitor::
1967 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1968 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001969 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001970}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001971void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001972 if (D)
1973 WL.push_back(MemberRefVisit(D, L, Parent));
1974}
1975void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1976 if (TI)
1977 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1978 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001979void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001980 unsigned size = WL.size();
Benjamin Kramer642f1732015-07-02 21:03:14 +00001981 for (const Stmt *SubStmt : S->children()) {
1982 AddStmt(SubStmt);
Guy Benyei11169dd2012-12-18 14:30:41 +00001983 }
1984 if (size == WL.size())
1985 return;
1986 // Now reverse the entries we just added. This will match the DFS
1987 // ordering performed by the worklist.
1988 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1989 std::reverse(I, E);
1990}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001991namespace {
1992class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1993 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001994 /// \brief Process clauses with list of variables.
1995 template <typename T>
1996 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001997public:
1998 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1999#define OPENMP_CLAUSE(Name, Class) \
2000 void Visit##Class(const Class *C);
2001#include "clang/Basic/OpenMPKinds.def"
2002};
2003
Alexey Bataevaadd52e2014-02-13 05:29:23 +00002004void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
2005 Visitor->AddStmt(C->getCondition());
2006}
2007
Alexey Bataev3778b602014-07-17 07:32:53 +00002008void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
2009 Visitor->AddStmt(C->getCondition());
2010}
2011
Alexey Bataev568a8332014-03-06 06:15:19 +00002012void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
2013 Visitor->AddStmt(C->getNumThreads());
2014}
2015
Alexey Bataev62c87d22014-03-21 04:51:18 +00002016void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
2017 Visitor->AddStmt(C->getSafelen());
2018}
2019
Alexander Musman8bd31e62014-05-27 15:12:19 +00002020void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
2021 Visitor->AddStmt(C->getNumForLoops());
2022}
2023
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002024void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00002025
Alexey Bataevbcbadb62014-05-06 06:04:14 +00002026void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
2027
Alexey Bataev56dafe82014-06-20 07:16:17 +00002028void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
2029 Visitor->AddStmt(C->getChunkSize());
Alexey Bataev040d5402015-05-12 08:35:28 +00002030 Visitor->AddStmt(C->getHelperChunkSize());
Alexey Bataev56dafe82014-06-20 07:16:17 +00002031}
2032
Alexey Bataev142e1fc2014-06-20 09:44:06 +00002033void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *) {}
2034
Alexey Bataev236070f2014-06-20 11:19:47 +00002035void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
2036
Alexey Bataev7aea99a2014-07-17 12:19:31 +00002037void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
2038
Alexey Bataev74ba3a52014-07-17 12:47:03 +00002039void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
2040
Alexey Bataevf98b00c2014-07-23 02:27:21 +00002041void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}
2042
Alexey Bataevdea47612014-07-23 07:46:59 +00002043void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {}
2044
Alexey Bataev67a4f222014-07-23 10:25:33 +00002045void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {}
2046
Alexey Bataev459dec02014-07-24 06:46:57 +00002047void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}
2048
Alexey Bataev82bad8b2014-07-24 08:55:34 +00002049void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
2050
Alexey Bataev756c1962013-09-24 03:17:45 +00002051template<typename T>
2052void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Alexey Bataev03b340a2014-10-21 03:16:40 +00002053 for (const auto *I : Node->varlists()) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00002054 Visitor->AddStmt(I);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002055 }
Alexey Bataev756c1962013-09-24 03:17:45 +00002056}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002057
2058void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002059 VisitOMPClauseList(C);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002060 for (const auto *E : C->private_copies()) {
2061 Visitor->AddStmt(E);
2062 }
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002063}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002064void OMPClauseEnqueue::VisitOMPFirstprivateClause(
2065 const OMPFirstprivateClause *C) {
2066 VisitOMPClauseList(C);
2067}
Alexander Musman1bb328c2014-06-04 13:06:39 +00002068void OMPClauseEnqueue::VisitOMPLastprivateClause(
2069 const OMPLastprivateClause *C) {
2070 VisitOMPClauseList(C);
Alexey Bataev38e89532015-04-16 04:54:05 +00002071 for (auto *E : C->private_copies()) {
2072 Visitor->AddStmt(E);
2073 }
2074 for (auto *E : C->source_exprs()) {
2075 Visitor->AddStmt(E);
2076 }
2077 for (auto *E : C->destination_exprs()) {
2078 Visitor->AddStmt(E);
2079 }
2080 for (auto *E : C->assignment_ops()) {
2081 Visitor->AddStmt(E);
2082 }
Alexander Musman1bb328c2014-06-04 13:06:39 +00002083}
Alexey Bataev758e55e2013-09-06 18:03:48 +00002084void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002085 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00002086}
Alexey Bataevc5e02582014-06-16 07:08:35 +00002087void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
2088 VisitOMPClauseList(C);
Alexey Bataev794ba0d2015-04-10 10:43:45 +00002089 for (auto *E : C->lhs_exprs()) {
2090 Visitor->AddStmt(E);
2091 }
2092 for (auto *E : C->rhs_exprs()) {
2093 Visitor->AddStmt(E);
2094 }
2095 for (auto *E : C->reduction_ops()) {
2096 Visitor->AddStmt(E);
2097 }
Alexey Bataevc5e02582014-06-16 07:08:35 +00002098}
Alexander Musman8dba6642014-04-22 13:09:42 +00002099void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2100 VisitOMPClauseList(C);
Alexander Musman3276a272015-03-21 10:12:56 +00002101 for (const auto *E : C->inits()) {
2102 Visitor->AddStmt(E);
2103 }
2104 for (const auto *E : C->updates()) {
2105 Visitor->AddStmt(E);
2106 }
2107 for (const auto *E : C->finals()) {
2108 Visitor->AddStmt(E);
2109 }
Alexander Musman8dba6642014-04-22 13:09:42 +00002110 Visitor->AddStmt(C->getStep());
Alexander Musman3276a272015-03-21 10:12:56 +00002111 Visitor->AddStmt(C->getCalcStep());
Alexander Musman8dba6642014-04-22 13:09:42 +00002112}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002113void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2114 VisitOMPClauseList(C);
2115 Visitor->AddStmt(C->getAlignment());
2116}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002117void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2118 VisitOMPClauseList(C);
Alexey Bataevf56f98c2015-04-16 05:39:01 +00002119 for (auto *E : C->source_exprs()) {
2120 Visitor->AddStmt(E);
2121 }
2122 for (auto *E : C->destination_exprs()) {
2123 Visitor->AddStmt(E);
2124 }
2125 for (auto *E : C->assignment_ops()) {
2126 Visitor->AddStmt(E);
2127 }
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002128}
Alexey Bataevbae9a792014-06-27 10:37:06 +00002129void
2130OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
2131 VisitOMPClauseList(C);
Alexey Bataeva63048e2015-03-23 06:18:07 +00002132 for (auto *E : C->source_exprs()) {
2133 Visitor->AddStmt(E);
2134 }
2135 for (auto *E : C->destination_exprs()) {
2136 Visitor->AddStmt(E);
2137 }
2138 for (auto *E : C->assignment_ops()) {
2139 Visitor->AddStmt(E);
2140 }
Alexey Bataevbae9a792014-06-27 10:37:06 +00002141}
Alexey Bataev6125da92014-07-21 11:26:11 +00002142void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2143 VisitOMPClauseList(C);
2144}
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +00002145void OMPClauseEnqueue::VisitOMPDependClause(const OMPDependClause *C) {
2146 VisitOMPClauseList(C);
2147}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002148}
Alexey Bataev756c1962013-09-24 03:17:45 +00002149
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002150void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2151 unsigned size = WL.size();
2152 OMPClauseEnqueue Visitor(this);
2153 Visitor.Visit(S);
2154 if (size == WL.size())
2155 return;
2156 // Now reverse the entries we just added. This will match the DFS
2157 // ordering performed by the worklist.
2158 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2159 std::reverse(I, E);
2160}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002161void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002162 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2163}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002164void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002165 AddDecl(B->getBlockDecl());
2166}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002167void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002168 EnqueueChildren(E);
2169 AddTypeLoc(E->getTypeSourceInfo());
2170}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002171void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
2172 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00002173 E = S->body_rend(); I != E; ++I) {
2174 AddStmt(*I);
2175 }
2176}
2177void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002178VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002179 AddStmt(S->getSubStmt());
2180 AddDeclarationNameInfo(S);
2181 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2182 AddNestedNameSpecifierLoc(QualifierLoc);
2183}
2184
2185void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002186VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002187 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2188 AddDeclarationNameInfo(E);
2189 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2190 AddNestedNameSpecifierLoc(QualifierLoc);
2191 if (!E->isImplicitAccess())
2192 AddStmt(E->getBase());
2193}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002194void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002195 // Enqueue the initializer , if any.
2196 AddStmt(E->getInitializer());
2197 // Enqueue the array size, if any.
2198 AddStmt(E->getArraySize());
2199 // Enqueue the allocated type.
2200 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2201 // Enqueue the placement arguments.
2202 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2203 AddStmt(E->getPlacementArg(I-1));
2204}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002205void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002206 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2207 AddStmt(CE->getArg(I-1));
2208 AddStmt(CE->getCallee());
2209 AddStmt(CE->getArg(0));
2210}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002211void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2212 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002213 // Visit the name of the type being destroyed.
2214 AddTypeLoc(E->getDestroyedTypeInfo());
2215 // Visit the scope type that looks disturbingly like the nested-name-specifier
2216 // but isn't.
2217 AddTypeLoc(E->getScopeTypeInfo());
2218 // Visit the nested-name-specifier.
2219 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2220 AddNestedNameSpecifierLoc(QualifierLoc);
2221 // Visit base expression.
2222 AddStmt(E->getBase());
2223}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002224void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2225 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002226 AddTypeLoc(E->getTypeSourceInfo());
2227}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002228void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2229 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002230 EnqueueChildren(E);
2231 AddTypeLoc(E->getTypeSourceInfo());
2232}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002233void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002234 EnqueueChildren(E);
2235 if (E->isTypeOperand())
2236 AddTypeLoc(E->getTypeOperandSourceInfo());
2237}
2238
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002239void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2240 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002241 EnqueueChildren(E);
2242 AddTypeLoc(E->getTypeSourceInfo());
2243}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002244void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002245 EnqueueChildren(E);
2246 if (E->isTypeOperand())
2247 AddTypeLoc(E->getTypeOperandSourceInfo());
2248}
2249
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002250void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002251 EnqueueChildren(S);
2252 AddDecl(S->getExceptionDecl());
2253}
2254
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002255void EnqueueVisitor::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002256 AddStmt(S->getBody());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002257 AddStmt(S->getRangeInit());
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002258 AddDecl(S->getLoopVariable());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002259}
2260
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002261void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002262 if (DR->hasExplicitTemplateArgs()) {
2263 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2264 }
2265 WL.push_back(DeclRefExprParts(DR, Parent));
2266}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002267void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2268 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002269 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2270 AddDeclarationNameInfo(E);
2271 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2272}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002273void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002274 unsigned size = WL.size();
2275 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002276 for (const auto *D : S->decls()) {
2277 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002278 isFirst = false;
2279 }
2280 if (size == WL.size())
2281 return;
2282 // Now reverse the entries we just added. This will match the DFS
2283 // ordering performed by the worklist.
2284 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2285 std::reverse(I, E);
2286}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002287void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002288 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002289 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002290 D = E->designators_rbegin(), DEnd = E->designators_rend();
2291 D != DEnd; ++D) {
2292 if (D->isFieldDesignator()) {
2293 if (FieldDecl *Field = D->getField())
2294 AddMemberRef(Field, D->getFieldLoc());
2295 continue;
2296 }
2297 if (D->isArrayDesignator()) {
2298 AddStmt(E->getArrayIndex(*D));
2299 continue;
2300 }
2301 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2302 AddStmt(E->getArrayRangeEnd(*D));
2303 AddStmt(E->getArrayRangeStart(*D));
2304 }
2305}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002306void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002307 EnqueueChildren(E);
2308 AddTypeLoc(E->getTypeInfoAsWritten());
2309}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002310void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002311 AddStmt(FS->getBody());
2312 AddStmt(FS->getInc());
2313 AddStmt(FS->getCond());
2314 AddDecl(FS->getConditionVariable());
2315 AddStmt(FS->getInit());
2316}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002317void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002318 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2319}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002320void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002321 AddStmt(If->getElse());
2322 AddStmt(If->getThen());
2323 AddStmt(If->getCond());
2324 AddDecl(If->getConditionVariable());
2325}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002326void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002327 // We care about the syntactic form of the initializer list, only.
2328 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2329 IE = Syntactic;
2330 EnqueueChildren(IE);
2331}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002332void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002333 WL.push_back(MemberExprParts(M, Parent));
2334
2335 // If the base of the member access expression is an implicit 'this', don't
2336 // visit it.
2337 // FIXME: If we ever want to show these implicit accesses, this will be
2338 // unfortunate. However, clang_getCursor() relies on this behavior.
Argyrios Kyrtzidis58d0e7a2015-03-13 04:40:07 +00002339 if (M->isImplicitAccess())
2340 return;
2341
2342 // Ignore base anonymous struct/union fields, otherwise they will shadow the
2343 // real field that that we are interested in.
2344 if (auto *SubME = dyn_cast<MemberExpr>(M->getBase())) {
2345 if (auto *FD = dyn_cast_or_null<FieldDecl>(SubME->getMemberDecl())) {
2346 if (FD->isAnonymousStructOrUnion()) {
2347 AddStmt(SubME->getBase());
2348 return;
2349 }
2350 }
2351 }
2352
2353 AddStmt(M->getBase());
Guy Benyei11169dd2012-12-18 14:30:41 +00002354}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002355void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002356 AddTypeLoc(E->getEncodedTypeSourceInfo());
2357}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002358void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002359 EnqueueChildren(M);
2360 AddTypeLoc(M->getClassReceiverTypeInfo());
2361}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002362void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002363 // Visit the components of the offsetof expression.
2364 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2365 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2366 const OffsetOfNode &Node = E->getComponent(I-1);
2367 switch (Node.getKind()) {
2368 case OffsetOfNode::Array:
2369 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2370 break;
2371 case OffsetOfNode::Field:
2372 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2373 break;
2374 case OffsetOfNode::Identifier:
2375 case OffsetOfNode::Base:
2376 continue;
2377 }
2378 }
2379 // Visit the type into which we're computing the offset.
2380 AddTypeLoc(E->getTypeSourceInfo());
2381}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002382void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002383 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2384 WL.push_back(OverloadExprParts(E, Parent));
2385}
2386void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002387 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002388 EnqueueChildren(E);
2389 if (E->isArgumentType())
2390 AddTypeLoc(E->getArgumentTypeInfo());
2391}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002392void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002393 EnqueueChildren(S);
2394}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002395void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002396 AddStmt(S->getBody());
2397 AddStmt(S->getCond());
2398 AddDecl(S->getConditionVariable());
2399}
2400
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002401void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002402 AddStmt(W->getBody());
2403 AddStmt(W->getCond());
2404 AddDecl(W->getConditionVariable());
2405}
2406
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002407void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002408 for (unsigned I = E->getNumArgs(); I > 0; --I)
2409 AddTypeLoc(E->getArg(I-1));
2410}
2411
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002412void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002413 AddTypeLoc(E->getQueriedTypeSourceInfo());
2414}
2415
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002416void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002417 EnqueueChildren(E);
2418}
2419
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002420void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002421 VisitOverloadExpr(U);
2422 if (!U->isImplicitAccess())
2423 AddStmt(U->getBase());
2424}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002425void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002426 AddStmt(E->getSubExpr());
2427 AddTypeLoc(E->getWrittenTypeInfo());
2428}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002429void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002430 WL.push_back(SizeOfPackExprParts(E, Parent));
2431}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002432void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002433 // If the opaque value has a source expression, just transparently
2434 // visit that. This is useful for (e.g.) pseudo-object expressions.
2435 if (Expr *SourceExpr = E->getSourceExpr())
2436 return Visit(SourceExpr);
2437}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002438void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002439 AddStmt(E->getBody());
2440 WL.push_back(LambdaExprParts(E, Parent));
2441}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002442void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002443 // Treat the expression like its syntactic form.
2444 Visit(E->getSyntacticForm());
2445}
2446
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002447void EnqueueVisitor::VisitOMPExecutableDirective(
2448 const OMPExecutableDirective *D) {
2449 EnqueueChildren(D);
2450 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2451 E = D->clauses().end();
2452 I != E; ++I)
2453 EnqueueChildren(*I);
2454}
2455
Alexander Musman3aaab662014-08-19 11:27:13 +00002456void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
2457 VisitOMPExecutableDirective(D);
2458}
2459
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002460void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2461 VisitOMPExecutableDirective(D);
2462}
2463
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002464void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002465 VisitOMPLoopDirective(D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002466}
2467
Alexey Bataevf29276e2014-06-18 04:14:57 +00002468void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002469 VisitOMPLoopDirective(D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002470}
2471
Alexander Musmanf82886e2014-09-18 05:12:34 +00002472void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
2473 VisitOMPLoopDirective(D);
2474}
2475
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002476void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2477 VisitOMPExecutableDirective(D);
2478}
2479
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002480void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2481 VisitOMPExecutableDirective(D);
2482}
2483
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002484void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2485 VisitOMPExecutableDirective(D);
2486}
2487
Alexander Musman80c22892014-07-17 08:54:58 +00002488void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2489 VisitOMPExecutableDirective(D);
2490}
2491
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002492void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2493 VisitOMPExecutableDirective(D);
2494 AddDeclarationNameInfo(D);
2495}
2496
Alexey Bataev4acb8592014-07-07 13:01:15 +00002497void
2498EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002499 VisitOMPLoopDirective(D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002500}
2501
Alexander Musmane4e893b2014-09-23 09:33:00 +00002502void EnqueueVisitor::VisitOMPParallelForSimdDirective(
2503 const OMPParallelForSimdDirective *D) {
2504 VisitOMPLoopDirective(D);
2505}
2506
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002507void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2508 const OMPParallelSectionsDirective *D) {
2509 VisitOMPExecutableDirective(D);
2510}
2511
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002512void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2513 VisitOMPExecutableDirective(D);
2514}
2515
Alexey Bataev68446b72014-07-18 07:47:19 +00002516void
2517EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2518 VisitOMPExecutableDirective(D);
2519}
2520
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002521void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2522 VisitOMPExecutableDirective(D);
2523}
2524
Alexey Bataev2df347a2014-07-18 10:17:07 +00002525void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2526 VisitOMPExecutableDirective(D);
2527}
2528
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002529void EnqueueVisitor::VisitOMPTaskgroupDirective(
2530 const OMPTaskgroupDirective *D) {
2531 VisitOMPExecutableDirective(D);
2532}
2533
Alexey Bataev6125da92014-07-21 11:26:11 +00002534void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2535 VisitOMPExecutableDirective(D);
2536}
2537
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002538void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2539 VisitOMPExecutableDirective(D);
2540}
2541
Alexey Bataev0162e452014-07-22 10:10:35 +00002542void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2543 VisitOMPExecutableDirective(D);
2544}
2545
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002546void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
2547 VisitOMPExecutableDirective(D);
2548}
2549
Alexey Bataev13314bf2014-10-09 04:18:56 +00002550void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {
2551 VisitOMPExecutableDirective(D);
2552}
2553
Alexey Bataev6d4ed052015-07-01 06:57:41 +00002554void EnqueueVisitor::VisitOMPCancellationPointDirective(
2555 const OMPCancellationPointDirective *D) {
2556 VisitOMPExecutableDirective(D);
2557}
2558
Alexey Bataev80909872015-07-02 11:25:17 +00002559void EnqueueVisitor::VisitOMPCancelDirective(const OMPCancelDirective *D) {
2560 VisitOMPExecutableDirective(D);
2561}
2562
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002563void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002564 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2565}
2566
2567bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2568 if (RegionOfInterest.isValid()) {
2569 SourceRange Range = getRawCursorExtent(C);
2570 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2571 return false;
2572 }
2573 return true;
2574}
2575
2576bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2577 while (!WL.empty()) {
2578 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002579 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002580
2581 // Set the Parent field, then back to its old value once we're done.
2582 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2583
2584 switch (LI.getKind()) {
2585 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002586 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002587 if (!D)
2588 continue;
2589
2590 // For now, perform default visitation for Decls.
2591 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2592 cast<DeclVisit>(&LI)->isFirst())))
2593 return true;
2594
2595 continue;
2596 }
2597 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2598 const ASTTemplateArgumentListInfo *ArgList =
2599 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2600 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2601 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2602 Arg != ArgEnd; ++Arg) {
2603 if (VisitTemplateArgumentLoc(*Arg))
2604 return true;
2605 }
2606 continue;
2607 }
2608 case VisitorJob::TypeLocVisitKind: {
2609 // Perform default visitation for TypeLocs.
2610 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2611 return true;
2612 continue;
2613 }
2614 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002615 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002616 if (LabelStmt *stmt = LS->getStmt()) {
2617 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2618 TU))) {
2619 return true;
2620 }
2621 }
2622 continue;
2623 }
2624
2625 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2626 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2627 if (VisitNestedNameSpecifierLoc(V->get()))
2628 return true;
2629 continue;
2630 }
2631
2632 case VisitorJob::DeclarationNameInfoVisitKind: {
2633 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2634 ->get()))
2635 return true;
2636 continue;
2637 }
2638 case VisitorJob::MemberRefVisitKind: {
2639 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2640 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2641 return true;
2642 continue;
2643 }
2644 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002645 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002646 if (!S)
2647 continue;
2648
2649 // Update the current cursor.
2650 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2651 if (!IsInRegionOfInterest(Cursor))
2652 continue;
2653 switch (Visitor(Cursor, Parent, ClientData)) {
2654 case CXChildVisit_Break: return true;
2655 case CXChildVisit_Continue: break;
2656 case CXChildVisit_Recurse:
2657 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002658 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002659 EnqueueWorkList(WL, S);
2660 break;
2661 }
2662 continue;
2663 }
2664 case VisitorJob::MemberExprPartsKind: {
2665 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002666 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002667
2668 // Visit the nested-name-specifier
2669 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2670 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2671 return true;
2672
2673 // Visit the declaration name.
2674 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2675 return true;
2676
2677 // Visit the explicitly-specified template arguments, if any.
2678 if (M->hasExplicitTemplateArgs()) {
2679 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2680 *ArgEnd = Arg + M->getNumTemplateArgs();
2681 Arg != ArgEnd; ++Arg) {
2682 if (VisitTemplateArgumentLoc(*Arg))
2683 return true;
2684 }
2685 }
2686 continue;
2687 }
2688 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002689 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002690 // Visit nested-name-specifier, if present.
2691 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2692 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2693 return true;
2694 // Visit declaration name.
2695 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2696 return true;
2697 continue;
2698 }
2699 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002700 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002701 // Visit the nested-name-specifier.
2702 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2703 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2704 return true;
2705 // Visit the declaration name.
2706 if (VisitDeclarationNameInfo(O->getNameInfo()))
2707 return true;
2708 // Visit the overloaded declaration reference.
2709 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2710 return true;
2711 continue;
2712 }
2713 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002714 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002715 NamedDecl *Pack = E->getPack();
2716 if (isa<TemplateTypeParmDecl>(Pack)) {
2717 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2718 E->getPackLoc(), TU)))
2719 return true;
2720
2721 continue;
2722 }
2723
2724 if (isa<TemplateTemplateParmDecl>(Pack)) {
2725 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2726 E->getPackLoc(), TU)))
2727 return true;
2728
2729 continue;
2730 }
2731
2732 // Non-type template parameter packs and function parameter packs are
2733 // treated like DeclRefExpr cursors.
2734 continue;
2735 }
2736
2737 case VisitorJob::LambdaExprPartsKind: {
2738 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002739 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002740 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2741 CEnd = E->explicit_capture_end();
2742 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002743 // FIXME: Lambda init-captures.
2744 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002745 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002746
Guy Benyei11169dd2012-12-18 14:30:41 +00002747 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2748 C->getLocation(),
2749 TU)))
2750 return true;
2751 }
2752
2753 // Visit parameters and return type, if present.
2754 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2755 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2756 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2757 // Visit the whole type.
2758 if (Visit(TL))
2759 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002760 } else if (FunctionProtoTypeLoc Proto =
2761 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002762 if (E->hasExplicitParameters()) {
2763 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002764 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2765 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002766 return true;
2767 } else {
2768 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002769 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002770 return true;
2771 }
2772 }
2773 }
2774 break;
2775 }
2776
2777 case VisitorJob::PostChildrenVisitKind:
2778 if (PostChildrenVisitor(Parent, ClientData))
2779 return true;
2780 break;
2781 }
2782 }
2783 return false;
2784}
2785
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002786bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002787 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002788 if (!WorkListFreeList.empty()) {
2789 WL = WorkListFreeList.back();
2790 WL->clear();
2791 WorkListFreeList.pop_back();
2792 }
2793 else {
2794 WL = new VisitorWorkList();
2795 WorkListCache.push_back(WL);
2796 }
2797 EnqueueWorkList(*WL, S);
2798 bool result = RunVisitorWorkList(*WL);
2799 WorkListFreeList.push_back(WL);
2800 return result;
2801}
2802
2803namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002804typedef SmallVector<SourceRange, 4> RefNamePieces;
Craig Topper69186e72014-06-08 08:38:04 +00002805RefNamePieces
2806buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2807 const DeclarationNameInfo &NI, const SourceRange &QLoc,
2808 const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002809 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2810 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2811 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2812
2813 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2814
2815 RefNamePieces Pieces;
2816
2817 if (WantQualifier && QLoc.isValid())
2818 Pieces.push_back(QLoc);
2819
2820 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2821 Pieces.push_back(NI.getLoc());
2822
2823 if (WantTemplateArgs && TemplateArgs)
2824 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2825 TemplateArgs->RAngleLoc));
2826
2827 if (Kind == DeclarationName::CXXOperatorName) {
2828 Pieces.push_back(SourceLocation::getFromRawEncoding(
2829 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2830 Pieces.push_back(SourceLocation::getFromRawEncoding(
2831 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2832 }
2833
2834 if (WantSinglePiece) {
2835 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2836 Pieces.clear();
2837 Pieces.push_back(R);
2838 }
2839
2840 return Pieces;
2841}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002842}
Guy Benyei11169dd2012-12-18 14:30:41 +00002843
2844//===----------------------------------------------------------------------===//
2845// Misc. API hooks.
2846//===----------------------------------------------------------------------===//
2847
Chad Rosier05c71aa2013-03-27 18:28:23 +00002848static void fatal_error_handler(void *user_data, const std::string& reason,
2849 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002850 // Write the result out to stderr avoiding errs() because raw_ostreams can
2851 // call report_fatal_error.
2852 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2853 ::abort();
2854}
2855
Chandler Carruth66660742014-06-27 16:37:27 +00002856namespace {
2857struct RegisterFatalErrorHandler {
2858 RegisterFatalErrorHandler() {
2859 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2860 }
2861};
2862}
2863
2864static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
2865
Guy Benyei11169dd2012-12-18 14:30:41 +00002866extern "C" {
2867CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2868 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002869 // We use crash recovery to make some of our APIs more reliable, implicitly
2870 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002871 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2872 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002873
Chandler Carruth66660742014-06-27 16:37:27 +00002874 // Look through the managed static to trigger construction of the managed
2875 // static which registers our fatal error handler. This ensures it is only
2876 // registered once.
2877 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00002878
2879 CIndexer *CIdxr = new CIndexer();
2880 if (excludeDeclarationsFromPCH)
2881 CIdxr->setOnlyLocalDecls();
2882 if (displayDiagnostics)
2883 CIdxr->setDisplayDiagnostics();
2884
2885 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2886 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2887 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2888 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2889 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2890 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2891
2892 return CIdxr;
2893}
2894
2895void clang_disposeIndex(CXIndex CIdx) {
2896 if (CIdx)
2897 delete static_cast<CIndexer *>(CIdx);
2898}
2899
2900void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2901 if (CIdx)
2902 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2903}
2904
2905unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2906 if (CIdx)
2907 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2908 return 0;
2909}
2910
2911void clang_toggleCrashRecovery(unsigned isEnabled) {
2912 if (isEnabled)
2913 llvm::CrashRecoveryContext::Enable();
2914 else
2915 llvm::CrashRecoveryContext::Disable();
2916}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002917
Guy Benyei11169dd2012-12-18 14:30:41 +00002918CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2919 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002920 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002921 enum CXErrorCode Result =
2922 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002923 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002924 assert((TU && Result == CXError_Success) ||
2925 (!TU && Result != CXError_Success));
2926 return TU;
2927}
2928
2929enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2930 const char *ast_filename,
2931 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002932 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002933 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002934
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002935 if (!CIdx || !ast_filename || !out_TU)
2936 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002937
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002938 LOG_FUNC_SECTION {
2939 *Log << ast_filename;
2940 }
2941
Guy Benyei11169dd2012-12-18 14:30:41 +00002942 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2943 FileSystemOptions FileSystemOpts;
2944
Justin Bognerd512c1e2014-10-15 00:33:06 +00002945 IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
2946 CompilerInstance::createDiagnostics(new DiagnosticOptions());
David Blaikie6f7382d2014-08-10 19:08:04 +00002947 std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
Adrian Prantlbb165fb2015-06-20 18:53:08 +00002948 ast_filename, CXXIdx->getPCHContainerOperations(), Diags, FileSystemOpts,
2949 CXXIdx->getOnlyLocalDecls(), None,
David Blaikie6f7382d2014-08-10 19:08:04 +00002950 /*CaptureDiagnostics=*/true,
2951 /*AllowPCHWithCompilerErrors=*/true,
2952 /*UserFilesAreVolatile=*/true);
2953 *out_TU = MakeCXTranslationUnit(CXXIdx, AU.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002954 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002955}
2956
2957unsigned clang_defaultEditingTranslationUnitOptions() {
2958 return CXTranslationUnit_PrecompiledPreamble |
2959 CXTranslationUnit_CacheCompletionResults;
2960}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002961
Guy Benyei11169dd2012-12-18 14:30:41 +00002962CXTranslationUnit
2963clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2964 const char *source_filename,
2965 int num_command_line_args,
2966 const char * const *command_line_args,
2967 unsigned num_unsaved_files,
2968 struct CXUnsavedFile *unsaved_files) {
2969 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2970 return clang_parseTranslationUnit(CIdx, source_filename,
2971 command_line_args, num_command_line_args,
2972 unsaved_files, num_unsaved_files,
2973 Options);
2974}
2975
2976struct ParseTranslationUnitInfo {
2977 CXIndex CIdx;
2978 const char *source_filename;
2979 const char *const *command_line_args;
2980 int num_command_line_args;
Alp Toker9d85b182014-07-07 01:23:14 +00002981 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00002982 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002983 CXTranslationUnit *out_TU;
Alp Toker5c532982014-07-07 22:42:03 +00002984 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002985};
2986static void clang_parseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00002987 const ParseTranslationUnitInfo *PTUI =
2988 static_cast<ParseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00002989 CXIndex CIdx = PTUI->CIdx;
2990 const char *source_filename = PTUI->source_filename;
2991 const char * const *command_line_args = PTUI->command_line_args;
2992 int num_command_line_args = PTUI->num_command_line_args;
Guy Benyei11169dd2012-12-18 14:30:41 +00002993 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002994 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002995
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002996 // Set up the initial return values.
2997 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002998 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002999
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003000 // Check arguments.
Alp Toker9d85b182014-07-07 01:23:14 +00003001 if (!CIdx || !out_TU) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003002 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00003003 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003004 }
3005
Guy Benyei11169dd2012-12-18 14:30:41 +00003006 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3007
3008 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3009 setThreadBackgroundPriority();
3010
3011 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
3012 // FIXME: Add a flag for modules.
3013 TranslationUnitKind TUKind
3014 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00003015 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00003016 = options & CXTranslationUnit_CacheCompletionResults;
3017 bool IncludeBriefCommentsInCodeCompletion
3018 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
3019 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
3020 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
3021
3022 // Configure the diagnostics.
3023 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00003024 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00003025
3026 // Recover resources if we crash before exiting this function.
3027 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
3028 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00003029 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00003030
Ahmed Charlesb8984322014-03-07 20:03:18 +00003031 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3032 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003033
3034 // Recover resources if we crash before exiting this function.
3035 llvm::CrashRecoveryContextCleanupRegistrar<
3036 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3037
Alp Toker9d85b182014-07-07 01:23:14 +00003038 for (auto &UF : PTUI->unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003039 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003040 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003041 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003042 }
3043
Ahmed Charlesb8984322014-03-07 20:03:18 +00003044 std::unique_ptr<std::vector<const char *>> Args(
3045 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003046
3047 // Recover resources if we crash before exiting this method.
3048 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
3049 ArgsCleanup(Args.get());
3050
3051 // Since the Clang C library is primarily used by batch tools dealing with
3052 // (often very broken) source code, where spell-checking can have a
3053 // significant negative impact on performance (particularly when
3054 // precompiled headers are involved), we disable it by default.
3055 // Only do this if we haven't found a spell-checking-related argument.
3056 bool FoundSpellCheckingArgument = false;
3057 for (int I = 0; I != num_command_line_args; ++I) {
3058 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
3059 strcmp(command_line_args[I], "-fspell-checking") == 0) {
3060 FoundSpellCheckingArgument = true;
3061 break;
3062 }
3063 }
3064 if (!FoundSpellCheckingArgument)
3065 Args->push_back("-fno-spell-checking");
3066
3067 Args->insert(Args->end(), command_line_args,
3068 command_line_args + num_command_line_args);
3069
3070 // The 'source_filename' argument is optional. If the caller does not
3071 // specify it then it is assumed that the source file is specified
3072 // in the actual argument list.
3073 // Put the source file after command_line_args otherwise if '-x' flag is
3074 // present it will be unused.
3075 if (source_filename)
3076 Args->push_back(source_filename);
3077
3078 // Do we need the detailed preprocessing record?
3079 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
3080 Args->push_back("-Xclang");
3081 Args->push_back("-detailed-preprocessing-record");
3082 }
3083
3084 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00003085 std::unique_ptr<ASTUnit> ErrUnit;
3086 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003087 Args->data(), Args->data() + Args->size(),
3088 CXXIdx->getPCHContainerOperations(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00003089 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
3090 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
3091 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
3092 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
3093 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
3094 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00003095
3096 if (NumErrors != Diags->getClient()->getNumErrors()) {
3097 // Make sure to check that 'Unit' is non-NULL.
3098 if (CXXIdx->getDisplayDiagnostics())
3099 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
3100 }
3101
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003102 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
3103 PTUI->result = CXError_ASTReadError;
3104 } else {
Ahmed Charles9a16beb2014-03-07 19:33:25 +00003105 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003106 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
3107 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003108}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003109
3110CXTranslationUnit
3111clang_parseTranslationUnit(CXIndex CIdx,
3112 const char *source_filename,
3113 const char *const *command_line_args,
3114 int num_command_line_args,
3115 struct CXUnsavedFile *unsaved_files,
3116 unsigned num_unsaved_files,
3117 unsigned options) {
3118 CXTranslationUnit TU;
3119 enum CXErrorCode Result = clang_parseTranslationUnit2(
3120 CIdx, source_filename, command_line_args, num_command_line_args,
3121 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00003122 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003123 assert((TU && Result == CXError_Success) ||
3124 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003125 return TU;
3126}
3127
3128enum CXErrorCode clang_parseTranslationUnit2(
3129 CXIndex CIdx,
3130 const char *source_filename,
3131 const char *const *command_line_args,
3132 int num_command_line_args,
3133 struct CXUnsavedFile *unsaved_files,
3134 unsigned num_unsaved_files,
3135 unsigned options,
3136 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003137 LOG_FUNC_SECTION {
3138 *Log << source_filename << ": ";
3139 for (int i = 0; i != num_command_line_args; ++i)
3140 *Log << command_line_args[i] << " ";
3141 }
3142
Alp Toker9d85b182014-07-07 01:23:14 +00003143 if (num_unsaved_files && !unsaved_files)
3144 return CXError_InvalidArguments;
3145
Alp Toker5c532982014-07-07 22:42:03 +00003146 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00003147 ParseTranslationUnitInfo PTUI = {
3148 CIdx,
3149 source_filename,
3150 command_line_args,
3151 num_command_line_args,
3152 llvm::makeArrayRef(unsaved_files, num_unsaved_files),
3153 options,
3154 out_TU,
Alp Toker5c532982014-07-07 22:42:03 +00003155 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00003156 llvm::CrashRecoveryContext CRC;
3157
3158 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
3159 fprintf(stderr, "libclang: crash detected during parsing: {\n");
3160 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3161 fprintf(stderr, " 'command_line_args' : [");
3162 for (int i = 0; i != num_command_line_args; ++i) {
3163 if (i)
3164 fprintf(stderr, ", ");
3165 fprintf(stderr, "'%s'", command_line_args[i]);
3166 }
3167 fprintf(stderr, "],\n");
3168 fprintf(stderr, " 'unsaved_files' : [");
3169 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3170 if (i)
3171 fprintf(stderr, ", ");
3172 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3173 unsaved_files[i].Length);
3174 }
3175 fprintf(stderr, "],\n");
3176 fprintf(stderr, " 'options' : %d,\n", options);
3177 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003178
3179 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003180 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003181 if (CXTranslationUnit *TU = PTUI.out_TU)
3182 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003183 }
Alp Toker5c532982014-07-07 22:42:03 +00003184
3185 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003186}
3187
3188unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
3189 return CXSaveTranslationUnit_None;
3190}
3191
3192namespace {
3193
3194struct SaveTranslationUnitInfo {
3195 CXTranslationUnit TU;
3196 const char *FileName;
3197 unsigned options;
3198 CXSaveError result;
3199};
3200
3201}
3202
3203static void clang_saveTranslationUnit_Impl(void *UserData) {
3204 SaveTranslationUnitInfo *STUI =
3205 static_cast<SaveTranslationUnitInfo*>(UserData);
3206
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003207 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003208 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3209 setThreadBackgroundPriority();
3210
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003211 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00003212 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
3213}
3214
3215int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3216 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003217 LOG_FUNC_SECTION {
3218 *Log << TU << ' ' << FileName;
3219 }
3220
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003221 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003222 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003223 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003224 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003225
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003226 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003227 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3228 if (!CXXUnit->hasSema())
3229 return CXSaveError_InvalidTU;
3230
3231 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
3232
3233 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3234 getenv("LIBCLANG_NOTHREADS")) {
3235 clang_saveTranslationUnit_Impl(&STUI);
3236
3237 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3238 PrintLibclangResourceUsage(TU);
3239
3240 return STUI.result;
3241 }
3242
3243 // We have an AST that has invalid nodes due to compiler errors.
3244 // Use a crash recovery thread for protection.
3245
3246 llvm::CrashRecoveryContext CRC;
3247
3248 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
3249 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3250 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3251 fprintf(stderr, " 'options' : %d,\n", options);
3252 fprintf(stderr, "}\n");
3253
3254 return CXSaveError_Unknown;
3255
3256 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3257 PrintLibclangResourceUsage(TU);
3258 }
3259
3260 return STUI.result;
3261}
3262
3263void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3264 if (CTUnit) {
3265 // If the translation unit has been marked as unsafe to free, just discard
3266 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003267 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3268 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003269 return;
3270
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003271 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003272 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003273 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3274 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003275 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003276 delete CTUnit;
3277 }
3278}
3279
3280unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3281 return CXReparse_None;
3282}
3283
3284struct ReparseTranslationUnitInfo {
3285 CXTranslationUnit TU;
Alp Toker9d85b182014-07-07 01:23:14 +00003286 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00003287 unsigned options;
Alp Toker5c532982014-07-07 22:42:03 +00003288 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003289};
3290
3291static void clang_reparseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00003292 const ReparseTranslationUnitInfo *RTUI =
3293 static_cast<ReparseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00003294 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003295 unsigned options = RTUI->options;
3296 (void) options;
3297
3298 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003299 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003300 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003301 RTUI->result = CXError_InvalidArguments;
3302 return;
3303 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003304
3305 // Reset the associated diagnostics.
3306 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003307 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003308
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003309 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003310 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3311 setThreadBackgroundPriority();
3312
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003313 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003314 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003315
3316 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3317 new std::vector<ASTUnit::RemappedFile>());
3318
Guy Benyei11169dd2012-12-18 14:30:41 +00003319 // Recover resources if we crash before exiting this function.
3320 llvm::CrashRecoveryContextCleanupRegistrar<
3321 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003322
3323 for (auto &UF : RTUI->unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003324 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003325 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003326 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003327 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003328
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003329 if (!CXXUnit->Reparse(CXXIdx->getPCHContainerOperations(),
3330 *RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003331 RTUI->result = CXError_Success;
3332 else if (isASTReadError(CXXUnit))
3333 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003334}
3335
3336int clang_reparseTranslationUnit(CXTranslationUnit TU,
3337 unsigned num_unsaved_files,
3338 struct CXUnsavedFile *unsaved_files,
3339 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003340 LOG_FUNC_SECTION {
3341 *Log << TU;
3342 }
3343
Alp Toker9d85b182014-07-07 01:23:14 +00003344 if (num_unsaved_files && !unsaved_files)
3345 return CXError_InvalidArguments;
3346
Alp Toker5c532982014-07-07 22:42:03 +00003347 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00003348 ReparseTranslationUnitInfo RTUI = {
3349 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options,
Alp Toker5c532982014-07-07 22:42:03 +00003350 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00003351
3352 if (getenv("LIBCLANG_NOTHREADS")) {
3353 clang_reparseTranslationUnit_Impl(&RTUI);
Alp Toker5c532982014-07-07 22:42:03 +00003354 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003355 }
3356
3357 llvm::CrashRecoveryContext CRC;
3358
3359 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3360 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003361 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003362 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003363 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3364 PrintLibclangResourceUsage(TU);
3365
Alp Toker5c532982014-07-07 22:42:03 +00003366 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003367}
3368
3369
3370CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003371 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003372 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003373 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003374 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003375
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003376 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003377 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003378}
3379
3380CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003381 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003382 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003383 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003384 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003385
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003386 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003387 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3388}
3389
3390} // end: extern "C"
3391
3392//===----------------------------------------------------------------------===//
3393// CXFile Operations.
3394//===----------------------------------------------------------------------===//
3395
3396extern "C" {
3397CXString clang_getFileName(CXFile SFile) {
3398 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003399 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003400
3401 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003402 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003403}
3404
3405time_t clang_getFileTime(CXFile SFile) {
3406 if (!SFile)
3407 return 0;
3408
3409 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3410 return FEnt->getModificationTime();
3411}
3412
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003413CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003414 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003415 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003416 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003417 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003418
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003419 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003420
3421 FileManager &FMgr = CXXUnit->getFileManager();
3422 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3423}
3424
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003425unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3426 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003427 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003428 LOG_BAD_TU(TU);
3429 return 0;
3430 }
3431
3432 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003433 return 0;
3434
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003435 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003436 FileEntry *FEnt = static_cast<FileEntry *>(file);
3437 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3438 .isFileMultipleIncludeGuarded(FEnt);
3439}
3440
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003441int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3442 if (!file || !outID)
3443 return 1;
3444
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003445 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003446 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3447 outID->data[0] = ID.getDevice();
3448 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003449 outID->data[2] = FEnt->getModificationTime();
3450 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003451}
3452
Argyrios Kyrtzidisac3997e2014-08-16 00:26:19 +00003453int clang_File_isEqual(CXFile file1, CXFile file2) {
3454 if (file1 == file2)
3455 return true;
3456
3457 if (!file1 || !file2)
3458 return false;
3459
3460 FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
3461 FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
3462 return FEnt1->getUniqueID() == FEnt2->getUniqueID();
3463}
3464
Guy Benyei11169dd2012-12-18 14:30:41 +00003465} // end: extern "C"
3466
3467//===----------------------------------------------------------------------===//
3468// CXCursor Operations.
3469//===----------------------------------------------------------------------===//
3470
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003471static const Decl *getDeclFromExpr(const Stmt *E) {
3472 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003473 return getDeclFromExpr(CE->getSubExpr());
3474
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003475 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003476 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003477 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003478 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003479 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003480 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003481 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003482 if (PRE->isExplicitProperty())
3483 return PRE->getExplicitProperty();
3484 // It could be messaging both getter and setter as in:
3485 // ++myobj.myprop;
3486 // in which case prefer to associate the setter since it is less obvious
3487 // from inspecting the source that the setter is going to get called.
3488 if (PRE->isMessagingSetter())
3489 return PRE->getImplicitPropertySetter();
3490 return PRE->getImplicitPropertyGetter();
3491 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003492 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003493 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003494 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003495 if (Expr *Src = OVE->getSourceExpr())
3496 return getDeclFromExpr(Src);
3497
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003498 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003499 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003500 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003501 if (!CE->isElidable())
3502 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003503 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003504 return OME->getMethodDecl();
3505
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003506 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003507 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003508 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003509 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3510 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003511 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003512 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3513 isa<ParmVarDecl>(SizeOfPack->getPack()))
3514 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003515
3516 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003517}
3518
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003519static SourceLocation getLocationFromExpr(const Expr *E) {
3520 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003521 return getLocationFromExpr(CE->getSubExpr());
3522
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003523 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003524 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003525 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003526 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003527 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003528 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003529 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003530 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003531 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003532 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003533 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003534 return PropRef->getLocation();
3535
3536 return E->getLocStart();
3537}
3538
3539extern "C" {
3540
3541unsigned clang_visitChildren(CXCursor parent,
3542 CXCursorVisitor visitor,
3543 CXClientData client_data) {
3544 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3545 /*VisitPreprocessorLast=*/false);
3546 return CursorVis.VisitChildren(parent);
3547}
3548
3549#ifndef __has_feature
3550#define __has_feature(x) 0
3551#endif
3552#if __has_feature(blocks)
3553typedef enum CXChildVisitResult
3554 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3555
3556static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3557 CXClientData client_data) {
3558 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3559 return block(cursor, parent);
3560}
3561#else
3562// If we are compiled with a compiler that doesn't have native blocks support,
3563// define and call the block manually, so the
3564typedef struct _CXChildVisitResult
3565{
3566 void *isa;
3567 int flags;
3568 int reserved;
3569 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3570 CXCursor);
3571} *CXCursorVisitorBlock;
3572
3573static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3574 CXClientData client_data) {
3575 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3576 return block->invoke(block, cursor, parent);
3577}
3578#endif
3579
3580
3581unsigned clang_visitChildrenWithBlock(CXCursor parent,
3582 CXCursorVisitorBlock block) {
3583 return clang_visitChildren(parent, visitWithBlock, block);
3584}
3585
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003586static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003587 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003588 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003589
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003590 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003591 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003592 if (const ObjCPropertyImplDecl *PropImpl =
3593 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003594 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003595 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003596
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003597 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003598 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003599 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003600
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003601 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003602 }
3603
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003604 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003605 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003606
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003607 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003608 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3609 // and returns different names. NamedDecl returns the class name and
3610 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003611 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003612
3613 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003614 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003615
3616 SmallString<1024> S;
3617 llvm::raw_svector_ostream os(S);
3618 ND->printName(os);
3619
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003620 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003621}
3622
3623CXString clang_getCursorSpelling(CXCursor C) {
3624 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003625 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003626
3627 if (clang_isReference(C.kind)) {
3628 switch (C.kind) {
3629 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003630 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003631 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003632 }
3633 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003634 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003635 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003636 }
3637 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003638 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003639 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003640 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003641 }
3642 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003643 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003644 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003645 }
3646 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003647 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003648 assert(Type && "Missing type decl");
3649
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003650 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003651 getAsString());
3652 }
3653 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003654 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003655 assert(Template && "Missing template decl");
3656
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003657 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003658 }
3659
3660 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003661 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003662 assert(NS && "Missing namespace decl");
3663
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003664 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003665 }
3666
3667 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003668 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003669 assert(Field && "Missing member decl");
3670
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003671 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003672 }
3673
3674 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003675 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003676 assert(Label && "Missing label");
3677
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003678 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003679 }
3680
3681 case CXCursor_OverloadedDeclRef: {
3682 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003683 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3684 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003685 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003686 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003687 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003688 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003689 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003690 OverloadedTemplateStorage *Ovl
3691 = Storage.get<OverloadedTemplateStorage*>();
3692 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003693 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003694 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003695 }
3696
3697 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003698 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003699 assert(Var && "Missing variable decl");
3700
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003701 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003702 }
3703
3704 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003705 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003706 }
3707 }
3708
3709 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003710 const Expr *E = getCursorExpr(C);
3711
3712 if (C.kind == CXCursor_ObjCStringLiteral ||
3713 C.kind == CXCursor_StringLiteral) {
3714 const StringLiteral *SLit;
3715 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3716 SLit = OSL->getString();
3717 } else {
3718 SLit = cast<StringLiteral>(E);
3719 }
3720 SmallString<256> Buf;
3721 llvm::raw_svector_ostream OS(Buf);
3722 SLit->outputString(OS);
3723 return cxstring::createDup(OS.str());
3724 }
3725
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003726 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003727 if (D)
3728 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003729 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003730 }
3731
3732 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003733 const Stmt *S = getCursorStmt(C);
3734 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003735 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003736
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003737 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003738 }
3739
3740 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003741 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003742 ->getNameStart());
3743
3744 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003745 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003746 ->getNameStart());
3747
3748 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003749 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003750
3751 if (clang_isDeclaration(C.kind))
3752 return getDeclSpelling(getCursorDecl(C));
3753
3754 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003755 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003756 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003757 }
3758
3759 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003760 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003761 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003762 }
3763
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003764 if (C.kind == CXCursor_PackedAttr) {
3765 return cxstring::createRef("packed");
3766 }
3767
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003768 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003769}
3770
3771CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3772 unsigned pieceIndex,
3773 unsigned options) {
3774 if (clang_Cursor_isNull(C))
3775 return clang_getNullRange();
3776
3777 ASTContext &Ctx = getCursorContext(C);
3778
3779 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003780 const Stmt *S = getCursorStmt(C);
3781 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003782 if (pieceIndex > 0)
3783 return clang_getNullRange();
3784 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3785 }
3786
3787 return clang_getNullRange();
3788 }
3789
3790 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003791 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003792 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3793 if (pieceIndex >= ME->getNumSelectorLocs())
3794 return clang_getNullRange();
3795 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3796 }
3797 }
3798
3799 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3800 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003801 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003802 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3803 if (pieceIndex >= MD->getNumSelectorLocs())
3804 return clang_getNullRange();
3805 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3806 }
3807 }
3808
3809 if (C.kind == CXCursor_ObjCCategoryDecl ||
3810 C.kind == CXCursor_ObjCCategoryImplDecl) {
3811 if (pieceIndex > 0)
3812 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003813 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003814 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3815 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003816 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003817 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3818 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3819 }
3820
3821 if (C.kind == CXCursor_ModuleImportDecl) {
3822 if (pieceIndex > 0)
3823 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003824 if (const ImportDecl *ImportD =
3825 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003826 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3827 if (!Locs.empty())
3828 return cxloc::translateSourceRange(Ctx,
3829 SourceRange(Locs.front(), Locs.back()));
3830 }
3831 return clang_getNullRange();
3832 }
3833
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00003834 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
3835 C.kind == CXCursor_ConversionFunction) {
3836 if (pieceIndex > 0)
3837 return clang_getNullRange();
3838 if (const FunctionDecl *FD =
3839 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
3840 DeclarationNameInfo FunctionName = FD->getNameInfo();
3841 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
3842 }
3843 return clang_getNullRange();
3844 }
3845
Guy Benyei11169dd2012-12-18 14:30:41 +00003846 // FIXME: A CXCursor_InclusionDirective should give the location of the
3847 // filename, but we don't keep track of this.
3848
3849 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3850 // but we don't keep track of this.
3851
3852 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3853 // but we don't keep track of this.
3854
3855 // Default handling, give the location of the cursor.
3856
3857 if (pieceIndex > 0)
3858 return clang_getNullRange();
3859
3860 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3861 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3862 return cxloc::translateSourceRange(Ctx, Loc);
3863}
3864
Eli Bendersky44a206f2014-07-31 18:04:56 +00003865CXString clang_Cursor_getMangling(CXCursor C) {
3866 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
3867 return cxstring::createEmpty();
3868
Eli Bendersky44a206f2014-07-31 18:04:56 +00003869 // Mangling only works for functions and variables.
Eli Bendersky79759592014-08-01 15:01:10 +00003870 const Decl *D = getCursorDecl(C);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003871 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
3872 return cxstring::createEmpty();
3873
Eli Bendersky79759592014-08-01 15:01:10 +00003874 // First apply frontend mangling.
Eli Bendersky44a206f2014-07-31 18:04:56 +00003875 const NamedDecl *ND = cast<NamedDecl>(D);
Eli Bendersky79759592014-08-01 15:01:10 +00003876 ASTContext &Ctx = ND->getASTContext();
3877 std::unique_ptr<MangleContext> MC(Ctx.createMangleContext());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003878
Eli Bendersky79759592014-08-01 15:01:10 +00003879 std::string FrontendBuf;
3880 llvm::raw_string_ostream FrontendBufOS(FrontendBuf);
3881 MC->mangleName(ND, FrontendBufOS);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003882
Eli Bendersky79759592014-08-01 15:01:10 +00003883 // Now apply backend mangling.
3884 std::unique_ptr<llvm::DataLayout> DL(
3885 new llvm::DataLayout(Ctx.getTargetInfo().getTargetDescription()));
Eli Bendersky79759592014-08-01 15:01:10 +00003886
3887 std::string FinalBuf;
3888 llvm::raw_string_ostream FinalBufOS(FinalBuf);
Rafael Espindolab633d202015-06-23 13:59:36 +00003889 llvm::Mangler::getNameWithPrefix(FinalBufOS, llvm::Twine(FrontendBufOS.str()),
3890 *DL);
Eli Bendersky79759592014-08-01 15:01:10 +00003891
3892 return cxstring::createDup(FinalBufOS.str());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003893}
3894
Guy Benyei11169dd2012-12-18 14:30:41 +00003895CXString clang_getCursorDisplayName(CXCursor C) {
3896 if (!clang_isDeclaration(C.kind))
3897 return clang_getCursorSpelling(C);
3898
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003899 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003900 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003901 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003902
3903 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003904 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003905 D = FunTmpl->getTemplatedDecl();
3906
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003907 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003908 SmallString<64> Str;
3909 llvm::raw_svector_ostream OS(Str);
3910 OS << *Function;
3911 if (Function->getPrimaryTemplate())
3912 OS << "<>";
3913 OS << "(";
3914 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3915 if (I)
3916 OS << ", ";
3917 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3918 }
3919
3920 if (Function->isVariadic()) {
3921 if (Function->getNumParams())
3922 OS << ", ";
3923 OS << "...";
3924 }
3925 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003926 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003927 }
3928
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003929 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003930 SmallString<64> Str;
3931 llvm::raw_svector_ostream OS(Str);
3932 OS << *ClassTemplate;
3933 OS << "<";
3934 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3935 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3936 if (I)
3937 OS << ", ";
3938
3939 NamedDecl *Param = Params->getParam(I);
3940 if (Param->getIdentifier()) {
3941 OS << Param->getIdentifier()->getName();
3942 continue;
3943 }
3944
3945 // There is no parameter name, which makes this tricky. Try to come up
3946 // with something useful that isn't too long.
3947 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3948 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3949 else if (NonTypeTemplateParmDecl *NTTP
3950 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3951 OS << NTTP->getType().getAsString(Policy);
3952 else
3953 OS << "template<...> class";
3954 }
3955
3956 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003957 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003958 }
3959
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003960 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003961 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3962 // If the type was explicitly written, use that.
3963 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003964 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003965
Benjamin Kramer9170e912013-02-22 15:46:01 +00003966 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003967 llvm::raw_svector_ostream OS(Str);
3968 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003969 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003970 ClassSpec->getTemplateArgs().data(),
3971 ClassSpec->getTemplateArgs().size(),
3972 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003973 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003974 }
3975
3976 return clang_getCursorSpelling(C);
3977}
3978
3979CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3980 switch (Kind) {
3981 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003982 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003983 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003984 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003985 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003986 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003987 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003988 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003989 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003990 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003991 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003992 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003993 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003994 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003995 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003996 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003997 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003998 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003999 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004000 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004001 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004002 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004003 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004004 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004005 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004006 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004007 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004008 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004009 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004010 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004011 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004012 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004013 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004014 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004015 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004016 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004017 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004018 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004019 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004020 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00004021 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004022 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004023 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004024 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004025 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004026 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004027 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004028 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004029 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004030 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004031 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004032 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004033 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004034 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004035 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004036 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004037 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004038 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004039 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004040 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004041 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004042 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004043 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004044 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004045 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004046 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004047 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004048 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004049 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004050 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004051 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004052 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004053 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004054 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004055 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004056 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004057 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004058 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004059 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004060 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004061 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004062 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004063 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004064 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004065 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004066 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004067 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004068 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004069 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004070 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004071 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004072 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004073 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004074 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004075 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004076 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004077 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004078 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004079 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004080 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004081 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004082 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004083 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004084 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004085 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004086 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004087 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004088 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004089 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004090 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004091 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004092 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004093 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004094 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004095 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004096 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004097 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004098 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004099 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004100 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004101 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004102 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004103 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004104 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004105 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004106 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004107 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004108 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00004109 case CXCursor_ObjCSelfExpr:
4110 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004111 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004112 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004113 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004114 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004115 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004116 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004117 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004118 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004119 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004120 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004121 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004122 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004123 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004124 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004125 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004126 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004127 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004128 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004129 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004130 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004131 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004132 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004133 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004134 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004135 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004136 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004137 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004138 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004139 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004140 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004141 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004142 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004143 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004144 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004145 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004146 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004147 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004148 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004149 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004150 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004151 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004152 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004153 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004154 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004155 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004156 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004157 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004158 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004159 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004160 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004161 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004162 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004163 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004164 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004165 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004166 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004167 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004168 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004169 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004170 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004171 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004172 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004173 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004174 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004175 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004176 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004177 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004178 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004179 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004180 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004181 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004182 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004183 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004184 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004185 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004186 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004187 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004188 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004189 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004190 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004191 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004192 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004193 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004194 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004195 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004196 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004197 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004198 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00004199 case CXCursor_SEHLeaveStmt:
4200 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004201 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004202 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004203 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004204 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00004205 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004206 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00004207 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004208 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00004209 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004210 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00004211 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004212 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00004213 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004214 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004215 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004216 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004217 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004218 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004219 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004220 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004221 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004222 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004223 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004224 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004225 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004226 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004227 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004228 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004229 case CXCursor_PackedAttr:
4230 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00004231 case CXCursor_PureAttr:
4232 return cxstring::createRef("attribute(pure)");
4233 case CXCursor_ConstAttr:
4234 return cxstring::createRef("attribute(const)");
4235 case CXCursor_NoDuplicateAttr:
4236 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00004237 case CXCursor_CUDAConstantAttr:
4238 return cxstring::createRef("attribute(constant)");
4239 case CXCursor_CUDADeviceAttr:
4240 return cxstring::createRef("attribute(device)");
4241 case CXCursor_CUDAGlobalAttr:
4242 return cxstring::createRef("attribute(global)");
4243 case CXCursor_CUDAHostAttr:
4244 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00004245 case CXCursor_CUDASharedAttr:
4246 return cxstring::createRef("attribute(shared)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004247 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004248 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004249 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004250 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00004251 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004252 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004253 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004254 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004255 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004256 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00004257 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004258 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00004259 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004260 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004261 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004262 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004263 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004264 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004265 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004266 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004267 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004268 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004269 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004270 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004271 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004272 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004273 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004274 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004275 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004276 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004277 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004278 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004279 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004280 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004281 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004282 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004283 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004284 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004285 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004286 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004287 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004288 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004289 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004290 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004291 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004292 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004293 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004294 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004295 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004296 return cxstring::createRef("OMPParallelDirective");
4297 case CXCursor_OMPSimdDirective:
4298 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004299 case CXCursor_OMPForDirective:
4300 return cxstring::createRef("OMPForDirective");
Alexander Musmanf82886e2014-09-18 05:12:34 +00004301 case CXCursor_OMPForSimdDirective:
4302 return cxstring::createRef("OMPForSimdDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004303 case CXCursor_OMPSectionsDirective:
4304 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004305 case CXCursor_OMPSectionDirective:
4306 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004307 case CXCursor_OMPSingleDirective:
4308 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004309 case CXCursor_OMPMasterDirective:
4310 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004311 case CXCursor_OMPCriticalDirective:
4312 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004313 case CXCursor_OMPParallelForDirective:
4314 return cxstring::createRef("OMPParallelForDirective");
Alexander Musmane4e893b2014-09-23 09:33:00 +00004315 case CXCursor_OMPParallelForSimdDirective:
4316 return cxstring::createRef("OMPParallelForSimdDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004317 case CXCursor_OMPParallelSectionsDirective:
4318 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004319 case CXCursor_OMPTaskDirective:
4320 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004321 case CXCursor_OMPTaskyieldDirective:
4322 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004323 case CXCursor_OMPBarrierDirective:
4324 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004325 case CXCursor_OMPTaskwaitDirective:
4326 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00004327 case CXCursor_OMPTaskgroupDirective:
4328 return cxstring::createRef("OMPTaskgroupDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00004329 case CXCursor_OMPFlushDirective:
4330 return cxstring::createRef("OMPFlushDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004331 case CXCursor_OMPOrderedDirective:
4332 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00004333 case CXCursor_OMPAtomicDirective:
4334 return cxstring::createRef("OMPAtomicDirective");
Alexey Bataev0bd520b2014-09-19 08:19:49 +00004335 case CXCursor_OMPTargetDirective:
4336 return cxstring::createRef("OMPTargetDirective");
Alexey Bataev13314bf2014-10-09 04:18:56 +00004337 case CXCursor_OMPTeamsDirective:
4338 return cxstring::createRef("OMPTeamsDirective");
Alexey Bataev6d4ed052015-07-01 06:57:41 +00004339 case CXCursor_OMPCancellationPointDirective:
4340 return cxstring::createRef("OMPCancellationPointDirective");
Alexey Bataev80909872015-07-02 11:25:17 +00004341 case CXCursor_OMPCancelDirective:
4342 return cxstring::createRef("OMPCancelDirective");
Francisco Lopes da Silva975a9f62015-01-21 16:24:11 +00004343 case CXCursor_OverloadCandidate:
4344 return cxstring::createRef("OverloadCandidate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004345 }
4346
4347 llvm_unreachable("Unhandled CXCursorKind");
4348}
4349
4350struct GetCursorData {
4351 SourceLocation TokenBeginLoc;
4352 bool PointsAtMacroArgExpansion;
4353 bool VisitedObjCPropertyImplDecl;
4354 SourceLocation VisitedDeclaratorDeclStartLoc;
4355 CXCursor &BestCursor;
4356
4357 GetCursorData(SourceManager &SM,
4358 SourceLocation tokenBegin, CXCursor &outputCursor)
4359 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4360 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4361 VisitedObjCPropertyImplDecl = false;
4362 }
4363};
4364
4365static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4366 CXCursor parent,
4367 CXClientData client_data) {
4368 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4369 CXCursor *BestCursor = &Data->BestCursor;
4370
4371 // If we point inside a macro argument we should provide info of what the
4372 // token is so use the actual cursor, don't replace it with a macro expansion
4373 // cursor.
4374 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4375 return CXChildVisit_Recurse;
4376
4377 if (clang_isDeclaration(cursor.kind)) {
4378 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004379 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004380 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4381 if (MD->isImplicit())
4382 return CXChildVisit_Break;
4383
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004384 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004385 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4386 // Check that when we have multiple @class references in the same line,
4387 // that later ones do not override the previous ones.
4388 // If we have:
4389 // @class Foo, Bar;
4390 // source ranges for both start at '@', so 'Bar' will end up overriding
4391 // 'Foo' even though the cursor location was at 'Foo'.
4392 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4393 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004394 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004395 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4396 if (PrevID != ID &&
4397 !PrevID->isThisDeclarationADefinition() &&
4398 !ID->isThisDeclarationADefinition())
4399 return CXChildVisit_Break;
4400 }
4401
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004402 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004403 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4404 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4405 // Check that when we have multiple declarators in the same line,
4406 // that later ones do not override the previous ones.
4407 // If we have:
4408 // int Foo, Bar;
4409 // source ranges for both start at 'int', so 'Bar' will end up overriding
4410 // 'Foo' even though the cursor location was at 'Foo'.
4411 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4412 return CXChildVisit_Break;
4413 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4414
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004415 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004416 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4417 (void)PropImp;
4418 // Check that when we have multiple @synthesize in the same line,
4419 // that later ones do not override the previous ones.
4420 // If we have:
4421 // @synthesize Foo, Bar;
4422 // source ranges for both start at '@', so 'Bar' will end up overriding
4423 // 'Foo' even though the cursor location was at 'Foo'.
4424 if (Data->VisitedObjCPropertyImplDecl)
4425 return CXChildVisit_Break;
4426 Data->VisitedObjCPropertyImplDecl = true;
4427 }
4428 }
4429
4430 if (clang_isExpression(cursor.kind) &&
4431 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004432 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004433 // Avoid having the cursor of an expression replace the declaration cursor
4434 // when the expression source range overlaps the declaration range.
4435 // This can happen for C++ constructor expressions whose range generally
4436 // include the variable declaration, e.g.:
4437 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4438 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4439 D->getLocation() == Data->TokenBeginLoc)
4440 return CXChildVisit_Break;
4441 }
4442 }
4443
4444 // If our current best cursor is the construction of a temporary object,
4445 // don't replace that cursor with a type reference, because we want
4446 // clang_getCursor() to point at the constructor.
4447 if (clang_isExpression(BestCursor->kind) &&
4448 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4449 cursor.kind == CXCursor_TypeRef) {
4450 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4451 // as having the actual point on the type reference.
4452 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4453 return CXChildVisit_Recurse;
4454 }
Douglas Gregore9d95f12015-07-07 03:57:35 +00004455
4456 // If we already have an Objective-C superclass reference, don't
4457 // update it further.
4458 if (BestCursor->kind == CXCursor_ObjCSuperClassRef)
4459 return CXChildVisit_Break;
4460
Guy Benyei11169dd2012-12-18 14:30:41 +00004461 *BestCursor = cursor;
4462 return CXChildVisit_Recurse;
4463}
4464
4465CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004466 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004467 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004468 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004469 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004470
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004471 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004472 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4473
4474 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4475 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4476
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004477 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004478 CXFile SearchFile;
4479 unsigned SearchLine, SearchColumn;
4480 CXFile ResultFile;
4481 unsigned ResultLine, ResultColumn;
4482 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4483 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4484 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004485
4486 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4487 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004488 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004489 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004490 SearchFileName = clang_getFileName(SearchFile);
4491 ResultFileName = clang_getFileName(ResultFile);
4492 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4493 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004494 *Log << llvm::format("(%s:%d:%d) = %s",
4495 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4496 clang_getCString(KindSpelling))
4497 << llvm::format("(%s:%d:%d):%s%s",
4498 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4499 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004500 clang_disposeString(SearchFileName);
4501 clang_disposeString(ResultFileName);
4502 clang_disposeString(KindSpelling);
4503 clang_disposeString(USR);
4504
4505 CXCursor Definition = clang_getCursorDefinition(Result);
4506 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4507 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4508 CXString DefinitionKindSpelling
4509 = clang_getCursorKindSpelling(Definition.kind);
4510 CXFile DefinitionFile;
4511 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004512 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004513 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004514 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004515 *Log << llvm::format(" -> %s(%s:%d:%d)",
4516 clang_getCString(DefinitionKindSpelling),
4517 clang_getCString(DefinitionFileName),
4518 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004519 clang_disposeString(DefinitionFileName);
4520 clang_disposeString(DefinitionKindSpelling);
4521 }
4522 }
4523
4524 return Result;
4525}
4526
4527CXCursor clang_getNullCursor(void) {
4528 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4529}
4530
4531unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004532 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4533 // can't set consistently. For example, when visiting a DeclStmt we will set
4534 // it but we don't set it on the result of clang_getCursorDefinition for
4535 // a reference of the same declaration.
4536 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4537 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4538 // to provide that kind of info.
4539 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004540 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004541 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004542 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004543
Guy Benyei11169dd2012-12-18 14:30:41 +00004544 return X == Y;
4545}
4546
4547unsigned clang_hashCursor(CXCursor C) {
4548 unsigned Index = 0;
4549 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4550 Index = 1;
4551
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004552 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004553 std::make_pair(C.kind, C.data[Index]));
4554}
4555
4556unsigned clang_isInvalid(enum CXCursorKind K) {
4557 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4558}
4559
4560unsigned clang_isDeclaration(enum CXCursorKind K) {
4561 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4562 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4563}
4564
4565unsigned clang_isReference(enum CXCursorKind K) {
4566 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4567}
4568
4569unsigned clang_isExpression(enum CXCursorKind K) {
4570 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4571}
4572
4573unsigned clang_isStatement(enum CXCursorKind K) {
4574 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4575}
4576
4577unsigned clang_isAttribute(enum CXCursorKind K) {
4578 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4579}
4580
4581unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4582 return K == CXCursor_TranslationUnit;
4583}
4584
4585unsigned clang_isPreprocessing(enum CXCursorKind K) {
4586 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4587}
4588
4589unsigned clang_isUnexposed(enum CXCursorKind K) {
4590 switch (K) {
4591 case CXCursor_UnexposedDecl:
4592 case CXCursor_UnexposedExpr:
4593 case CXCursor_UnexposedStmt:
4594 case CXCursor_UnexposedAttr:
4595 return true;
4596 default:
4597 return false;
4598 }
4599}
4600
4601CXCursorKind clang_getCursorKind(CXCursor C) {
4602 return C.kind;
4603}
4604
4605CXSourceLocation clang_getCursorLocation(CXCursor C) {
4606 if (clang_isReference(C.kind)) {
4607 switch (C.kind) {
4608 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004609 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004610 = getCursorObjCSuperClassRef(C);
4611 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4612 }
4613
4614 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004615 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004616 = getCursorObjCProtocolRef(C);
4617 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4618 }
4619
4620 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004621 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004622 = getCursorObjCClassRef(C);
4623 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4624 }
4625
4626 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004627 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004628 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4629 }
4630
4631 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004632 std::pair<const TemplateDecl *, SourceLocation> P =
4633 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004634 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4635 }
4636
4637 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004638 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004639 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4640 }
4641
4642 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004643 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004644 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4645 }
4646
4647 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004648 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004649 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4650 }
4651
4652 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004653 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004654 if (!BaseSpec)
4655 return clang_getNullLocation();
4656
4657 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4658 return cxloc::translateSourceLocation(getCursorContext(C),
4659 TSInfo->getTypeLoc().getBeginLoc());
4660
4661 return cxloc::translateSourceLocation(getCursorContext(C),
4662 BaseSpec->getLocStart());
4663 }
4664
4665 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004666 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004667 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4668 }
4669
4670 case CXCursor_OverloadedDeclRef:
4671 return cxloc::translateSourceLocation(getCursorContext(C),
4672 getCursorOverloadedDeclRef(C).second);
4673
4674 default:
4675 // FIXME: Need a way to enumerate all non-reference cases.
4676 llvm_unreachable("Missed a reference kind");
4677 }
4678 }
4679
4680 if (clang_isExpression(C.kind))
4681 return cxloc::translateSourceLocation(getCursorContext(C),
4682 getLocationFromExpr(getCursorExpr(C)));
4683
4684 if (clang_isStatement(C.kind))
4685 return cxloc::translateSourceLocation(getCursorContext(C),
4686 getCursorStmt(C)->getLocStart());
4687
4688 if (C.kind == CXCursor_PreprocessingDirective) {
4689 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4690 return cxloc::translateSourceLocation(getCursorContext(C), L);
4691 }
4692
4693 if (C.kind == CXCursor_MacroExpansion) {
4694 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004695 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004696 return cxloc::translateSourceLocation(getCursorContext(C), L);
4697 }
4698
4699 if (C.kind == CXCursor_MacroDefinition) {
4700 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4701 return cxloc::translateSourceLocation(getCursorContext(C), L);
4702 }
4703
4704 if (C.kind == CXCursor_InclusionDirective) {
4705 SourceLocation L
4706 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4707 return cxloc::translateSourceLocation(getCursorContext(C), L);
4708 }
4709
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004710 if (clang_isAttribute(C.kind)) {
4711 SourceLocation L
4712 = cxcursor::getCursorAttr(C)->getLocation();
4713 return cxloc::translateSourceLocation(getCursorContext(C), L);
4714 }
4715
Guy Benyei11169dd2012-12-18 14:30:41 +00004716 if (!clang_isDeclaration(C.kind))
4717 return clang_getNullLocation();
4718
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004719 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004720 if (!D)
4721 return clang_getNullLocation();
4722
4723 SourceLocation Loc = D->getLocation();
4724 // FIXME: Multiple variables declared in a single declaration
4725 // currently lack the information needed to correctly determine their
4726 // ranges when accounting for the type-specifier. We use context
4727 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4728 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004729 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004730 if (!cxcursor::isFirstInDeclGroup(C))
4731 Loc = VD->getLocation();
4732 }
4733
4734 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004735 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004736 Loc = MD->getSelectorStartLoc();
4737
4738 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4739}
4740
4741} // end extern "C"
4742
4743CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4744 assert(TU);
4745
4746 // Guard against an invalid SourceLocation, or we may assert in one
4747 // of the following calls.
4748 if (SLoc.isInvalid())
4749 return clang_getNullCursor();
4750
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004751 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004752
4753 // Translate the given source location to make it point at the beginning of
4754 // the token under the cursor.
4755 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4756 CXXUnit->getASTContext().getLangOpts());
4757
4758 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4759 if (SLoc.isValid()) {
4760 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4761 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4762 /*VisitPreprocessorLast=*/true,
4763 /*VisitIncludedEntities=*/false,
4764 SourceLocation(SLoc));
4765 CursorVis.visitFileRegion();
4766 }
4767
4768 return Result;
4769}
4770
4771static SourceRange getRawCursorExtent(CXCursor C) {
4772 if (clang_isReference(C.kind)) {
4773 switch (C.kind) {
4774 case CXCursor_ObjCSuperClassRef:
4775 return getCursorObjCSuperClassRef(C).second;
4776
4777 case CXCursor_ObjCProtocolRef:
4778 return getCursorObjCProtocolRef(C).second;
4779
4780 case CXCursor_ObjCClassRef:
4781 return getCursorObjCClassRef(C).second;
4782
4783 case CXCursor_TypeRef:
4784 return getCursorTypeRef(C).second;
4785
4786 case CXCursor_TemplateRef:
4787 return getCursorTemplateRef(C).second;
4788
4789 case CXCursor_NamespaceRef:
4790 return getCursorNamespaceRef(C).second;
4791
4792 case CXCursor_MemberRef:
4793 return getCursorMemberRef(C).second;
4794
4795 case CXCursor_CXXBaseSpecifier:
4796 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4797
4798 case CXCursor_LabelRef:
4799 return getCursorLabelRef(C).second;
4800
4801 case CXCursor_OverloadedDeclRef:
4802 return getCursorOverloadedDeclRef(C).second;
4803
4804 case CXCursor_VariableRef:
4805 return getCursorVariableRef(C).second;
4806
4807 default:
4808 // FIXME: Need a way to enumerate all non-reference cases.
4809 llvm_unreachable("Missed a reference kind");
4810 }
4811 }
4812
4813 if (clang_isExpression(C.kind))
4814 return getCursorExpr(C)->getSourceRange();
4815
4816 if (clang_isStatement(C.kind))
4817 return getCursorStmt(C)->getSourceRange();
4818
4819 if (clang_isAttribute(C.kind))
4820 return getCursorAttr(C)->getRange();
4821
4822 if (C.kind == CXCursor_PreprocessingDirective)
4823 return cxcursor::getCursorPreprocessingDirective(C);
4824
4825 if (C.kind == CXCursor_MacroExpansion) {
4826 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004827 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004828 return TU->mapRangeFromPreamble(Range);
4829 }
4830
4831 if (C.kind == CXCursor_MacroDefinition) {
4832 ASTUnit *TU = getCursorASTUnit(C);
4833 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4834 return TU->mapRangeFromPreamble(Range);
4835 }
4836
4837 if (C.kind == CXCursor_InclusionDirective) {
4838 ASTUnit *TU = getCursorASTUnit(C);
4839 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4840 return TU->mapRangeFromPreamble(Range);
4841 }
4842
4843 if (C.kind == CXCursor_TranslationUnit) {
4844 ASTUnit *TU = getCursorASTUnit(C);
4845 FileID MainID = TU->getSourceManager().getMainFileID();
4846 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4847 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4848 return SourceRange(Start, End);
4849 }
4850
4851 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004852 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004853 if (!D)
4854 return SourceRange();
4855
4856 SourceRange R = D->getSourceRange();
4857 // FIXME: Multiple variables declared in a single declaration
4858 // currently lack the information needed to correctly determine their
4859 // ranges when accounting for the type-specifier. We use context
4860 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4861 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004862 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004863 if (!cxcursor::isFirstInDeclGroup(C))
4864 R.setBegin(VD->getLocation());
4865 }
4866 return R;
4867 }
4868 return SourceRange();
4869}
4870
4871/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4872/// the decl-specifier-seq for declarations.
4873static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4874 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004875 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004876 if (!D)
4877 return SourceRange();
4878
4879 SourceRange R = D->getSourceRange();
4880
4881 // Adjust the start of the location for declarations preceded by
4882 // declaration specifiers.
4883 SourceLocation StartLoc;
4884 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4885 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4886 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004887 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004888 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4889 StartLoc = TI->getTypeLoc().getLocStart();
4890 }
4891
4892 if (StartLoc.isValid() && R.getBegin().isValid() &&
4893 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4894 R.setBegin(StartLoc);
4895
4896 // FIXME: Multiple variables declared in a single declaration
4897 // currently lack the information needed to correctly determine their
4898 // ranges when accounting for the type-specifier. We use context
4899 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4900 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004901 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004902 if (!cxcursor::isFirstInDeclGroup(C))
4903 R.setBegin(VD->getLocation());
4904 }
4905
4906 return R;
4907 }
4908
4909 return getRawCursorExtent(C);
4910}
4911
4912extern "C" {
4913
4914CXSourceRange clang_getCursorExtent(CXCursor C) {
4915 SourceRange R = getRawCursorExtent(C);
4916 if (R.isInvalid())
4917 return clang_getNullRange();
4918
4919 return cxloc::translateSourceRange(getCursorContext(C), R);
4920}
4921
4922CXCursor clang_getCursorReferenced(CXCursor C) {
4923 if (clang_isInvalid(C.kind))
4924 return clang_getNullCursor();
4925
4926 CXTranslationUnit tu = getCursorTU(C);
4927 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004928 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004929 if (!D)
4930 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004931 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004932 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004933 if (const ObjCPropertyImplDecl *PropImpl =
4934 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004935 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4936 return MakeCXCursor(Property, tu);
4937
4938 return C;
4939 }
4940
4941 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004942 const Expr *E = getCursorExpr(C);
4943 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004944 if (D) {
4945 CXCursor declCursor = MakeCXCursor(D, tu);
4946 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4947 declCursor);
4948 return declCursor;
4949 }
4950
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004951 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004952 return MakeCursorOverloadedDeclRef(Ovl, tu);
4953
4954 return clang_getNullCursor();
4955 }
4956
4957 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004958 const Stmt *S = getCursorStmt(C);
4959 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004960 if (LabelDecl *label = Goto->getLabel())
4961 if (LabelStmt *labelS = label->getStmt())
4962 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4963
4964 return clang_getNullCursor();
4965 }
Richard Smith66a81862015-05-04 02:25:31 +00004966
Guy Benyei11169dd2012-12-18 14:30:41 +00004967 if (C.kind == CXCursor_MacroExpansion) {
Richard Smith66a81862015-05-04 02:25:31 +00004968 if (const MacroDefinitionRecord *Def =
4969 getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004970 return MakeMacroDefinitionCursor(Def, tu);
4971 }
4972
4973 if (!clang_isReference(C.kind))
4974 return clang_getNullCursor();
4975
4976 switch (C.kind) {
4977 case CXCursor_ObjCSuperClassRef:
4978 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4979
4980 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004981 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4982 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004983 return MakeCXCursor(Def, tu);
4984
4985 return MakeCXCursor(Prot, tu);
4986 }
4987
4988 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004989 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4990 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004991 return MakeCXCursor(Def, tu);
4992
4993 return MakeCXCursor(Class, tu);
4994 }
4995
4996 case CXCursor_TypeRef:
4997 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4998
4999 case CXCursor_TemplateRef:
5000 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
5001
5002 case CXCursor_NamespaceRef:
5003 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
5004
5005 case CXCursor_MemberRef:
5006 return MakeCXCursor(getCursorMemberRef(C).first, tu );
5007
5008 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005009 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005010 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
5011 tu ));
5012 }
5013
5014 case CXCursor_LabelRef:
5015 // FIXME: We end up faking the "parent" declaration here because we
5016 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005017 return MakeCXCursor(getCursorLabelRef(C).first,
5018 cxtu::getASTUnit(tu)->getASTContext()
5019 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00005020 tu);
5021
5022 case CXCursor_OverloadedDeclRef:
5023 return C;
5024
5025 case CXCursor_VariableRef:
5026 return MakeCXCursor(getCursorVariableRef(C).first, tu);
5027
5028 default:
5029 // We would prefer to enumerate all non-reference cursor kinds here.
5030 llvm_unreachable("Unhandled reference cursor kind");
5031 }
5032}
5033
5034CXCursor clang_getCursorDefinition(CXCursor C) {
5035 if (clang_isInvalid(C.kind))
5036 return clang_getNullCursor();
5037
5038 CXTranslationUnit TU = getCursorTU(C);
5039
5040 bool WasReference = false;
5041 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
5042 C = clang_getCursorReferenced(C);
5043 WasReference = true;
5044 }
5045
5046 if (C.kind == CXCursor_MacroExpansion)
5047 return clang_getCursorReferenced(C);
5048
5049 if (!clang_isDeclaration(C.kind))
5050 return clang_getNullCursor();
5051
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005052 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005053 if (!D)
5054 return clang_getNullCursor();
5055
5056 switch (D->getKind()) {
5057 // Declaration kinds that don't really separate the notions of
5058 // declaration and definition.
5059 case Decl::Namespace:
5060 case Decl::Typedef:
5061 case Decl::TypeAlias:
5062 case Decl::TypeAliasTemplate:
5063 case Decl::TemplateTypeParm:
5064 case Decl::EnumConstant:
5065 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00005066 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005067 case Decl::IndirectField:
5068 case Decl::ObjCIvar:
5069 case Decl::ObjCAtDefsField:
5070 case Decl::ImplicitParam:
5071 case Decl::ParmVar:
5072 case Decl::NonTypeTemplateParm:
5073 case Decl::TemplateTemplateParm:
5074 case Decl::ObjCCategoryImpl:
5075 case Decl::ObjCImplementation:
5076 case Decl::AccessSpec:
5077 case Decl::LinkageSpec:
5078 case Decl::ObjCPropertyImpl:
5079 case Decl::FileScopeAsm:
5080 case Decl::StaticAssert:
5081 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00005082 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00005083 case Decl::Label: // FIXME: Is this right??
5084 case Decl::ClassScopeFunctionSpecialization:
5085 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00005086 case Decl::OMPThreadPrivate:
Douglas Gregor85f3f952015-07-07 03:57:15 +00005087 case Decl::ObjCTypeParam:
Guy Benyei11169dd2012-12-18 14:30:41 +00005088 return C;
5089
5090 // Declaration kinds that don't make any sense here, but are
5091 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00005092 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005093 case Decl::TranslationUnit:
Richard Smithf19e1272015-03-07 00:04:49 +00005094 case Decl::ExternCContext:
Guy Benyei11169dd2012-12-18 14:30:41 +00005095 break;
5096
5097 // Declaration kinds for which the definition is not resolvable.
5098 case Decl::UnresolvedUsingTypename:
5099 case Decl::UnresolvedUsingValue:
5100 break;
5101
5102 case Decl::UsingDirective:
5103 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
5104 TU);
5105
5106 case Decl::NamespaceAlias:
5107 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
5108
5109 case Decl::Enum:
5110 case Decl::Record:
5111 case Decl::CXXRecord:
5112 case Decl::ClassTemplateSpecialization:
5113 case Decl::ClassTemplatePartialSpecialization:
5114 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
5115 return MakeCXCursor(Def, TU);
5116 return clang_getNullCursor();
5117
5118 case Decl::Function:
5119 case Decl::CXXMethod:
5120 case Decl::CXXConstructor:
5121 case Decl::CXXDestructor:
5122 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00005123 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005124 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00005125 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005126 return clang_getNullCursor();
5127 }
5128
Larisse Voufo39a1e502013-08-06 01:03:05 +00005129 case Decl::Var:
5130 case Decl::VarTemplateSpecialization:
5131 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00005132 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005133 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005134 return MakeCXCursor(Def, TU);
5135 return clang_getNullCursor();
5136 }
5137
5138 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00005139 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005140 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
5141 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
5142 return clang_getNullCursor();
5143 }
5144
5145 case Decl::ClassTemplate: {
5146 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
5147 ->getDefinition())
5148 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
5149 TU);
5150 return clang_getNullCursor();
5151 }
5152
Larisse Voufo39a1e502013-08-06 01:03:05 +00005153 case Decl::VarTemplate: {
5154 if (VarDecl *Def =
5155 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
5156 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
5157 return clang_getNullCursor();
5158 }
5159
Guy Benyei11169dd2012-12-18 14:30:41 +00005160 case Decl::Using:
5161 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
5162 D->getLocation(), TU);
5163
5164 case Decl::UsingShadow:
5165 return clang_getCursorDefinition(
5166 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
5167 TU));
5168
5169 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005170 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005171 if (Method->isThisDeclarationADefinition())
5172 return C;
5173
5174 // Dig out the method definition in the associated
5175 // @implementation, if we have it.
5176 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005177 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005178 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
5179 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
5180 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
5181 Method->isInstanceMethod()))
5182 if (Def->isThisDeclarationADefinition())
5183 return MakeCXCursor(Def, TU);
5184
5185 return clang_getNullCursor();
5186 }
5187
5188 case Decl::ObjCCategory:
5189 if (ObjCCategoryImplDecl *Impl
5190 = cast<ObjCCategoryDecl>(D)->getImplementation())
5191 return MakeCXCursor(Impl, TU);
5192 return clang_getNullCursor();
5193
5194 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005195 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005196 return MakeCXCursor(Def, TU);
5197 return clang_getNullCursor();
5198
5199 case Decl::ObjCInterface: {
5200 // There are two notions of a "definition" for an Objective-C
5201 // class: the interface and its implementation. When we resolved a
5202 // reference to an Objective-C class, produce the @interface as
5203 // the definition; when we were provided with the interface,
5204 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005205 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005206 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005207 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005208 return MakeCXCursor(Def, TU);
5209 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
5210 return MakeCXCursor(Impl, TU);
5211 return clang_getNullCursor();
5212 }
5213
5214 case Decl::ObjCProperty:
5215 // FIXME: We don't really know where to find the
5216 // ObjCPropertyImplDecls that implement this property.
5217 return clang_getNullCursor();
5218
5219 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005220 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005221 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005222 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005223 return MakeCXCursor(Def, TU);
5224
5225 return clang_getNullCursor();
5226
5227 case Decl::Friend:
5228 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
5229 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5230 return clang_getNullCursor();
5231
5232 case Decl::FriendTemplate:
5233 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
5234 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5235 return clang_getNullCursor();
5236 }
5237
5238 return clang_getNullCursor();
5239}
5240
5241unsigned clang_isCursorDefinition(CXCursor C) {
5242 if (!clang_isDeclaration(C.kind))
5243 return 0;
5244
5245 return clang_getCursorDefinition(C) == C;
5246}
5247
5248CXCursor clang_getCanonicalCursor(CXCursor C) {
5249 if (!clang_isDeclaration(C.kind))
5250 return C;
5251
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005252 if (const Decl *D = getCursorDecl(C)) {
5253 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005254 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5255 return MakeCXCursor(CatD, getCursorTU(C));
5256
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005257 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5258 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00005259 return MakeCXCursor(IFD, getCursorTU(C));
5260
5261 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5262 }
5263
5264 return C;
5265}
5266
5267int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5268 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5269}
5270
5271unsigned clang_getNumOverloadedDecls(CXCursor C) {
5272 if (C.kind != CXCursor_OverloadedDeclRef)
5273 return 0;
5274
5275 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005276 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005277 return E->getNumDecls();
5278
5279 if (OverloadedTemplateStorage *S
5280 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5281 return S->size();
5282
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005283 const Decl *D = Storage.get<const Decl *>();
5284 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005285 return Using->shadow_size();
5286
5287 return 0;
5288}
5289
5290CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5291 if (cursor.kind != CXCursor_OverloadedDeclRef)
5292 return clang_getNullCursor();
5293
5294 if (index >= clang_getNumOverloadedDecls(cursor))
5295 return clang_getNullCursor();
5296
5297 CXTranslationUnit TU = getCursorTU(cursor);
5298 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005299 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005300 return MakeCXCursor(E->decls_begin()[index], TU);
5301
5302 if (OverloadedTemplateStorage *S
5303 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5304 return MakeCXCursor(S->begin()[index], TU);
5305
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005306 const Decl *D = Storage.get<const Decl *>();
5307 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005308 // FIXME: This is, unfortunately, linear time.
5309 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5310 std::advance(Pos, index);
5311 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5312 }
5313
5314 return clang_getNullCursor();
5315}
5316
5317void clang_getDefinitionSpellingAndExtent(CXCursor C,
5318 const char **startBuf,
5319 const char **endBuf,
5320 unsigned *startLine,
5321 unsigned *startColumn,
5322 unsigned *endLine,
5323 unsigned *endColumn) {
5324 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005325 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005326 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5327
5328 SourceManager &SM = FD->getASTContext().getSourceManager();
5329 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5330 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5331 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5332 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5333 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5334 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5335}
5336
5337
5338CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5339 unsigned PieceIndex) {
5340 RefNamePieces Pieces;
5341
5342 switch (C.kind) {
5343 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005344 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005345 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5346 E->getQualifierLoc().getSourceRange());
5347 break;
5348
5349 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005350 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005351 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
5352 E->getQualifierLoc().getSourceRange(),
5353 E->getOptionalExplicitTemplateArgs());
5354 break;
5355
5356 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005357 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005358 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005359 const Expr *Callee = OCE->getCallee();
5360 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005361 Callee = ICE->getSubExpr();
5362
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005363 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005364 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5365 DRE->getQualifierLoc().getSourceRange());
5366 }
5367 break;
5368
5369 default:
5370 break;
5371 }
5372
5373 if (Pieces.empty()) {
5374 if (PieceIndex == 0)
5375 return clang_getCursorExtent(C);
5376 } else if (PieceIndex < Pieces.size()) {
5377 SourceRange R = Pieces[PieceIndex];
5378 if (R.isValid())
5379 return cxloc::translateSourceRange(getCursorContext(C), R);
5380 }
5381
5382 return clang_getNullRange();
5383}
5384
5385void clang_enableStackTraces(void) {
5386 llvm::sys::PrintStackTraceOnErrorSignal();
5387}
5388
5389void clang_executeOnThread(void (*fn)(void*), void *user_data,
5390 unsigned stack_size) {
5391 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5392}
5393
5394} // end: extern "C"
5395
5396//===----------------------------------------------------------------------===//
5397// Token-based Operations.
5398//===----------------------------------------------------------------------===//
5399
5400/* CXToken layout:
5401 * int_data[0]: a CXTokenKind
5402 * int_data[1]: starting token location
5403 * int_data[2]: token length
5404 * int_data[3]: reserved
5405 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5406 * otherwise unused.
5407 */
5408extern "C" {
5409
5410CXTokenKind clang_getTokenKind(CXToken CXTok) {
5411 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5412}
5413
5414CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5415 switch (clang_getTokenKind(CXTok)) {
5416 case CXToken_Identifier:
5417 case CXToken_Keyword:
5418 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005419 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005420 ->getNameStart());
5421
5422 case CXToken_Literal: {
5423 // We have stashed the starting pointer in the ptr_data field. Use it.
5424 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005425 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005426 }
5427
5428 case CXToken_Punctuation:
5429 case CXToken_Comment:
5430 break;
5431 }
5432
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005433 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005434 LOG_BAD_TU(TU);
5435 return cxstring::createEmpty();
5436 }
5437
Guy Benyei11169dd2012-12-18 14:30:41 +00005438 // We have to find the starting buffer pointer the hard way, by
5439 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005440 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005441 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005442 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005443
5444 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5445 std::pair<FileID, unsigned> LocInfo
5446 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5447 bool Invalid = false;
5448 StringRef Buffer
5449 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5450 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005451 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005452
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005453 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005454}
5455
5456CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005457 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005458 LOG_BAD_TU(TU);
5459 return clang_getNullLocation();
5460 }
5461
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005462 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005463 if (!CXXUnit)
5464 return clang_getNullLocation();
5465
5466 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5467 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5468}
5469
5470CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005471 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005472 LOG_BAD_TU(TU);
5473 return clang_getNullRange();
5474 }
5475
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005476 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005477 if (!CXXUnit)
5478 return clang_getNullRange();
5479
5480 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5481 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5482}
5483
5484static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5485 SmallVectorImpl<CXToken> &CXTokens) {
5486 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5487 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005488 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005489 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005490 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005491
5492 // Cannot tokenize across files.
5493 if (BeginLocInfo.first != EndLocInfo.first)
5494 return;
5495
5496 // Create a lexer
5497 bool Invalid = false;
5498 StringRef Buffer
5499 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5500 if (Invalid)
5501 return;
5502
5503 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5504 CXXUnit->getASTContext().getLangOpts(),
5505 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5506 Lex.SetCommentRetentionState(true);
5507
5508 // Lex tokens until we hit the end of the range.
5509 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5510 Token Tok;
5511 bool previousWasAt = false;
5512 do {
5513 // Lex the next token
5514 Lex.LexFromRawLexer(Tok);
5515 if (Tok.is(tok::eof))
5516 break;
5517
5518 // Initialize the CXToken.
5519 CXToken CXTok;
5520
5521 // - Common fields
5522 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5523 CXTok.int_data[2] = Tok.getLength();
5524 CXTok.int_data[3] = 0;
5525
5526 // - Kind-specific fields
5527 if (Tok.isLiteral()) {
5528 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005529 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005530 } else if (Tok.is(tok::raw_identifier)) {
5531 // Lookup the identifier to determine whether we have a keyword.
5532 IdentifierInfo *II
5533 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5534
5535 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5536 CXTok.int_data[0] = CXToken_Keyword;
5537 }
5538 else {
5539 CXTok.int_data[0] = Tok.is(tok::identifier)
5540 ? CXToken_Identifier
5541 : CXToken_Keyword;
5542 }
5543 CXTok.ptr_data = II;
5544 } else if (Tok.is(tok::comment)) {
5545 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005546 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005547 } else {
5548 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005549 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005550 }
5551 CXTokens.push_back(CXTok);
5552 previousWasAt = Tok.is(tok::at);
5553 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5554}
5555
5556void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5557 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005558 LOG_FUNC_SECTION {
5559 *Log << TU << ' ' << Range;
5560 }
5561
Guy Benyei11169dd2012-12-18 14:30:41 +00005562 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005563 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005564 if (NumTokens)
5565 *NumTokens = 0;
5566
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005567 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005568 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005569 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005570 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005571
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005572 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005573 if (!CXXUnit || !Tokens || !NumTokens)
5574 return;
5575
5576 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5577
5578 SourceRange R = cxloc::translateCXSourceRange(Range);
5579 if (R.isInvalid())
5580 return;
5581
5582 SmallVector<CXToken, 32> CXTokens;
5583 getTokens(CXXUnit, R, CXTokens);
5584
5585 if (CXTokens.empty())
5586 return;
5587
5588 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5589 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5590 *NumTokens = CXTokens.size();
5591}
5592
5593void clang_disposeTokens(CXTranslationUnit TU,
5594 CXToken *Tokens, unsigned NumTokens) {
5595 free(Tokens);
5596}
5597
5598} // end: extern "C"
5599
5600//===----------------------------------------------------------------------===//
5601// Token annotation APIs.
5602//===----------------------------------------------------------------------===//
5603
Guy Benyei11169dd2012-12-18 14:30:41 +00005604static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5605 CXCursor parent,
5606 CXClientData client_data);
5607static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5608 CXClientData client_data);
5609
5610namespace {
5611class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005612 CXToken *Tokens;
5613 CXCursor *Cursors;
5614 unsigned NumTokens;
5615 unsigned TokIdx;
5616 unsigned PreprocessingTokIdx;
5617 CursorVisitor AnnotateVis;
5618 SourceManager &SrcMgr;
5619 bool HasContextSensitiveKeywords;
5620
5621 struct PostChildrenInfo {
5622 CXCursor Cursor;
5623 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005624 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005625 unsigned BeforeChildrenTokenIdx;
5626 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005627 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005628
5629 CXToken &getTok(unsigned Idx) {
5630 assert(Idx < NumTokens);
5631 return Tokens[Idx];
5632 }
5633 const CXToken &getTok(unsigned Idx) const {
5634 assert(Idx < NumTokens);
5635 return Tokens[Idx];
5636 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005637 bool MoreTokens() const { return TokIdx < NumTokens; }
5638 unsigned NextToken() const { return TokIdx; }
5639 void AdvanceToken() { ++TokIdx; }
5640 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005641 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005642 }
5643 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005644 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005645 }
5646 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005647 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005648 }
5649
5650 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005651 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005652 SourceRange);
5653
5654public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005655 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005656 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005657 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005658 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005659 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005660 AnnotateTokensVisitor, this,
5661 /*VisitPreprocessorLast=*/true,
5662 /*VisitIncludedEntities=*/false,
5663 RegionOfInterest,
5664 /*VisitDeclsOnly=*/false,
5665 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005666 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005667 HasContextSensitiveKeywords(false) { }
5668
5669 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5670 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5671 bool postVisitChildren(CXCursor cursor);
5672 void AnnotateTokens();
5673
5674 /// \brief Determine whether the annotator saw any cursors that have
5675 /// context-sensitive keywords.
5676 bool hasContextSensitiveKeywords() const {
5677 return HasContextSensitiveKeywords;
5678 }
5679
5680 ~AnnotateTokensWorker() {
5681 assert(PostChildrenInfos.empty());
5682 }
5683};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00005684}
Guy Benyei11169dd2012-12-18 14:30:41 +00005685
5686void AnnotateTokensWorker::AnnotateTokens() {
5687 // Walk the AST within the region of interest, annotating tokens
5688 // along the way.
5689 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005690}
Guy Benyei11169dd2012-12-18 14:30:41 +00005691
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005692static inline void updateCursorAnnotation(CXCursor &Cursor,
5693 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005694 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005695 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005696 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005697}
5698
5699/// \brief It annotates and advances tokens with a cursor until the comparison
5700//// between the cursor location and the source range is the same as
5701/// \arg compResult.
5702///
5703/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5704/// Pass RangeOverlap to annotate tokens inside a range.
5705void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5706 RangeComparisonResult compResult,
5707 SourceRange range) {
5708 while (MoreTokens()) {
5709 const unsigned I = NextToken();
5710 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005711 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5712 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005713
5714 SourceLocation TokLoc = GetTokenLoc(I);
5715 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005716 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005717 AdvanceToken();
5718 continue;
5719 }
5720 break;
5721 }
5722}
5723
5724/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005725/// \returns true if it advanced beyond all macro tokens, false otherwise.
5726bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005727 CXCursor updateC,
5728 RangeComparisonResult compResult,
5729 SourceRange range) {
5730 assert(MoreTokens());
5731 assert(isFunctionMacroToken(NextToken()) &&
5732 "Should be called only for macro arg tokens");
5733
5734 // This works differently than annotateAndAdvanceTokens; because expanded
5735 // macro arguments can have arbitrary translation-unit source order, we do not
5736 // advance the token index one by one until a token fails the range test.
5737 // We only advance once past all of the macro arg tokens if all of them
5738 // pass the range test. If one of them fails we keep the token index pointing
5739 // at the start of the macro arg tokens so that the failing token will be
5740 // annotated by a subsequent annotation try.
5741
5742 bool atLeastOneCompFail = false;
5743
5744 unsigned I = NextToken();
5745 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5746 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5747 if (TokLoc.isFileID())
5748 continue; // not macro arg token, it's parens or comma.
5749 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5750 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5751 Cursors[I] = updateC;
5752 } else
5753 atLeastOneCompFail = true;
5754 }
5755
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005756 if (atLeastOneCompFail)
5757 return false;
5758
5759 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5760 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005761}
5762
5763enum CXChildVisitResult
5764AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005765 SourceRange cursorRange = getRawCursorExtent(cursor);
5766 if (cursorRange.isInvalid())
5767 return CXChildVisit_Recurse;
5768
5769 if (!HasContextSensitiveKeywords) {
5770 // Objective-C properties can have context-sensitive keywords.
5771 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005772 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005773 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5774 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5775 }
5776 // Objective-C methods can have context-sensitive keywords.
5777 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5778 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005779 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005780 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5781 if (Method->getObjCDeclQualifier())
5782 HasContextSensitiveKeywords = true;
5783 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005784 for (const auto *P : Method->params()) {
5785 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005786 HasContextSensitiveKeywords = true;
5787 break;
5788 }
5789 }
5790 }
5791 }
5792 }
5793 // C++ methods can have context-sensitive keywords.
5794 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005795 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005796 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5797 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5798 HasContextSensitiveKeywords = true;
5799 }
5800 }
5801 // C++ classes can have context-sensitive keywords.
5802 else if (cursor.kind == CXCursor_StructDecl ||
5803 cursor.kind == CXCursor_ClassDecl ||
5804 cursor.kind == CXCursor_ClassTemplate ||
5805 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005806 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005807 if (D->hasAttr<FinalAttr>())
5808 HasContextSensitiveKeywords = true;
5809 }
5810 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005811
5812 // Don't override a property annotation with its getter/setter method.
5813 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5814 parent.kind == CXCursor_ObjCPropertyDecl)
5815 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005816
5817 if (clang_isPreprocessing(cursor.kind)) {
5818 // Items in the preprocessing record are kept separate from items in
5819 // declarations, so we keep a separate token index.
5820 unsigned SavedTokIdx = TokIdx;
5821 TokIdx = PreprocessingTokIdx;
5822
5823 // Skip tokens up until we catch up to the beginning of the preprocessing
5824 // entry.
5825 while (MoreTokens()) {
5826 const unsigned I = NextToken();
5827 SourceLocation TokLoc = GetTokenLoc(I);
5828 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5829 case RangeBefore:
5830 AdvanceToken();
5831 continue;
5832 case RangeAfter:
5833 case RangeOverlap:
5834 break;
5835 }
5836 break;
5837 }
5838
5839 // Look at all of the tokens within this range.
5840 while (MoreTokens()) {
5841 const unsigned I = NextToken();
5842 SourceLocation TokLoc = GetTokenLoc(I);
5843 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5844 case RangeBefore:
5845 llvm_unreachable("Infeasible");
5846 case RangeAfter:
5847 break;
5848 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005849 // For macro expansions, just note where the beginning of the macro
5850 // expansion occurs.
5851 if (cursor.kind == CXCursor_MacroExpansion) {
5852 if (TokLoc == cursorRange.getBegin())
5853 Cursors[I] = cursor;
5854 AdvanceToken();
5855 break;
5856 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005857 // We may have already annotated macro names inside macro definitions.
5858 if (Cursors[I].kind != CXCursor_MacroExpansion)
5859 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005860 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005861 continue;
5862 }
5863 break;
5864 }
5865
5866 // Save the preprocessing token index; restore the non-preprocessing
5867 // token index.
5868 PreprocessingTokIdx = TokIdx;
5869 TokIdx = SavedTokIdx;
5870 return CXChildVisit_Recurse;
5871 }
5872
5873 if (cursorRange.isInvalid())
5874 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005875
5876 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005877 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005878 const enum CXCursorKind K = clang_getCursorKind(parent);
5879 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005880 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5881 // Attributes are annotated out-of-order, skip tokens until we reach it.
5882 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005883 ? clang_getNullCursor() : parent;
5884
5885 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5886
5887 // Avoid having the cursor of an expression "overwrite" the annotation of the
5888 // variable declaration that it belongs to.
5889 // This can happen for C++ constructor expressions whose range generally
5890 // include the variable declaration, e.g.:
5891 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005892 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005893 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005894 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005895 const unsigned I = NextToken();
5896 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5897 E->getLocStart() == D->getLocation() &&
5898 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005899 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005900 AdvanceToken();
5901 }
5902 }
5903 }
5904
5905 // Before recursing into the children keep some state that we are going
5906 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5907 // extra work after the child nodes are visited.
5908 // Note that we don't call VisitChildren here to avoid traversing statements
5909 // code-recursively which can blow the stack.
5910
5911 PostChildrenInfo Info;
5912 Info.Cursor = cursor;
5913 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005914 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005915 Info.BeforeChildrenTokenIdx = NextToken();
5916 PostChildrenInfos.push_back(Info);
5917
5918 return CXChildVisit_Recurse;
5919}
5920
5921bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5922 if (PostChildrenInfos.empty())
5923 return false;
5924 const PostChildrenInfo &Info = PostChildrenInfos.back();
5925 if (!clang_equalCursors(Info.Cursor, cursor))
5926 return false;
5927
5928 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5929 const unsigned AfterChildren = NextToken();
5930 SourceRange cursorRange = Info.CursorRange;
5931
5932 // Scan the tokens that are at the end of the cursor, but are not captured
5933 // but the child cursors.
5934 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5935
5936 // Scan the tokens that are at the beginning of the cursor, but are not
5937 // capture by the child cursors.
5938 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5939 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5940 break;
5941
5942 Cursors[I] = cursor;
5943 }
5944
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005945 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5946 // encountered the attribute cursor.
5947 if (clang_isAttribute(cursor.kind))
5948 TokIdx = Info.BeforeReachingCursorIdx;
5949
Guy Benyei11169dd2012-12-18 14:30:41 +00005950 PostChildrenInfos.pop_back();
5951 return false;
5952}
5953
5954static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5955 CXCursor parent,
5956 CXClientData client_data) {
5957 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5958}
5959
5960static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5961 CXClientData client_data) {
5962 return static_cast<AnnotateTokensWorker*>(client_data)->
5963 postVisitChildren(cursor);
5964}
5965
5966namespace {
5967
5968/// \brief Uses the macro expansions in the preprocessing record to find
5969/// and mark tokens that are macro arguments. This info is used by the
5970/// AnnotateTokensWorker.
5971class MarkMacroArgTokensVisitor {
5972 SourceManager &SM;
5973 CXToken *Tokens;
5974 unsigned NumTokens;
5975 unsigned CurIdx;
5976
5977public:
5978 MarkMacroArgTokensVisitor(SourceManager &SM,
5979 CXToken *tokens, unsigned numTokens)
5980 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5981
5982 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5983 if (cursor.kind != CXCursor_MacroExpansion)
5984 return CXChildVisit_Continue;
5985
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005986 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005987 if (macroRange.getBegin() == macroRange.getEnd())
5988 return CXChildVisit_Continue; // it's not a function macro.
5989
5990 for (; CurIdx < NumTokens; ++CurIdx) {
5991 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5992 macroRange.getBegin()))
5993 break;
5994 }
5995
5996 if (CurIdx == NumTokens)
5997 return CXChildVisit_Break;
5998
5999 for (; CurIdx < NumTokens; ++CurIdx) {
6000 SourceLocation tokLoc = getTokenLoc(CurIdx);
6001 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
6002 break;
6003
6004 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
6005 }
6006
6007 if (CurIdx == NumTokens)
6008 return CXChildVisit_Break;
6009
6010 return CXChildVisit_Continue;
6011 }
6012
6013private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006014 CXToken &getTok(unsigned Idx) {
6015 assert(Idx < NumTokens);
6016 return Tokens[Idx];
6017 }
6018 const CXToken &getTok(unsigned Idx) const {
6019 assert(Idx < NumTokens);
6020 return Tokens[Idx];
6021 }
6022
Guy Benyei11169dd2012-12-18 14:30:41 +00006023 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006024 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006025 }
6026
6027 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
6028 // The third field is reserved and currently not used. Use it here
6029 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006030 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00006031 }
6032};
6033
6034} // end anonymous namespace
6035
6036static CXChildVisitResult
6037MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
6038 CXClientData client_data) {
6039 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
6040 parent);
6041}
6042
6043namespace {
6044 struct clang_annotateTokens_Data {
6045 CXTranslationUnit TU;
6046 ASTUnit *CXXUnit;
6047 CXToken *Tokens;
6048 unsigned NumTokens;
6049 CXCursor *Cursors;
6050 };
6051}
6052
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006053/// \brief Used by \c annotatePreprocessorTokens.
6054/// \returns true if lexing was finished, false otherwise.
6055static bool lexNext(Lexer &Lex, Token &Tok,
6056 unsigned &NextIdx, unsigned NumTokens) {
6057 if (NextIdx >= NumTokens)
6058 return true;
6059
6060 ++NextIdx;
6061 Lex.LexFromRawLexer(Tok);
6062 if (Tok.is(tok::eof))
6063 return true;
6064
6065 return false;
6066}
6067
Guy Benyei11169dd2012-12-18 14:30:41 +00006068static void annotatePreprocessorTokens(CXTranslationUnit TU,
6069 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006070 CXCursor *Cursors,
6071 CXToken *Tokens,
6072 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006073 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006074
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006075 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00006076 SourceManager &SourceMgr = CXXUnit->getSourceManager();
6077 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006078 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00006079 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006080 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00006081
6082 if (BeginLocInfo.first != EndLocInfo.first)
6083 return;
6084
6085 StringRef Buffer;
6086 bool Invalid = false;
6087 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
6088 if (Buffer.empty() || Invalid)
6089 return;
6090
6091 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
6092 CXXUnit->getASTContext().getLangOpts(),
6093 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
6094 Buffer.end());
6095 Lex.SetCommentRetentionState(true);
6096
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006097 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006098 // Lex tokens in raw mode until we hit the end of the range, to avoid
6099 // entering #includes or expanding macros.
6100 while (true) {
6101 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006102 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6103 break;
6104 unsigned TokIdx = NextIdx-1;
6105 assert(Tok.getLocation() ==
6106 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006107
6108 reprocess:
6109 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006110 // We have found a preprocessing directive. Annotate the tokens
6111 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00006112 //
6113 // FIXME: Some simple tests here could identify macro definitions and
6114 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006115
6116 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006117 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6118 break;
6119
Craig Topper69186e72014-06-08 08:38:04 +00006120 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00006121 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006122 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6123 break;
6124
6125 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00006126 IdentifierInfo &II =
6127 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006128 SourceLocation MappedTokLoc =
6129 CXXUnit->mapLocationToPreamble(Tok.getLocation());
6130 MI = getMacroInfo(II, MappedTokLoc, TU);
6131 }
6132 }
6133
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006134 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00006135 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006136 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
6137 finished = true;
6138 break;
6139 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006140 // If we are in a macro definition, check if the token was ever a
6141 // macro name and annotate it if that's the case.
6142 if (MI) {
6143 SourceLocation SaveLoc = Tok.getLocation();
6144 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
Richard Smith66a81862015-05-04 02:25:31 +00006145 MacroDefinitionRecord *MacroDef =
6146 checkForMacroInMacroDefinition(MI, Tok, TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006147 Tok.setLocation(SaveLoc);
6148 if (MacroDef)
Richard Smith66a81862015-05-04 02:25:31 +00006149 Cursors[NextIdx - 1] =
6150 MakeMacroExpansionCursor(MacroDef, Tok.getLocation(), TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006151 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006152 } while (!Tok.isAtStartOfLine());
6153
6154 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
6155 assert(TokIdx <= LastIdx);
6156 SourceLocation EndLoc =
6157 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
6158 CXCursor Cursor =
6159 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
6160
6161 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006162 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006163
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006164 if (finished)
6165 break;
6166 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00006167 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006168 }
6169}
6170
6171// This gets run a separate thread to avoid stack blowout.
6172static void clang_annotateTokensImpl(void *UserData) {
6173 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
6174 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
6175 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
6176 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
6177 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
6178
Dmitri Gribenko183436e2013-01-26 21:49:50 +00006179 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006180 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
6181 setThreadBackgroundPriority();
6182
6183 // Determine the region of interest, which contains all of the tokens.
6184 SourceRange RegionOfInterest;
6185 RegionOfInterest.setBegin(
6186 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
6187 RegionOfInterest.setEnd(
6188 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
6189 Tokens[NumTokens-1])));
6190
Guy Benyei11169dd2012-12-18 14:30:41 +00006191 // Relex the tokens within the source range to look for preprocessing
6192 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006193 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006194
6195 // If begin location points inside a macro argument, set it to the expansion
6196 // location so we can have the full context when annotating semantically.
6197 {
6198 SourceManager &SM = CXXUnit->getSourceManager();
6199 SourceLocation Loc =
6200 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
6201 if (Loc.isMacroID())
6202 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
6203 }
6204
Guy Benyei11169dd2012-12-18 14:30:41 +00006205 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
6206 // Search and mark tokens that are macro argument expansions.
6207 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
6208 Tokens, NumTokens);
6209 CursorVisitor MacroArgMarker(TU,
6210 MarkMacroArgTokensVisitorDelegate, &Visitor,
6211 /*VisitPreprocessorLast=*/true,
6212 /*VisitIncludedEntities=*/false,
6213 RegionOfInterest);
6214 MacroArgMarker.visitPreprocessedEntitiesInRegion();
6215 }
6216
6217 // Annotate all of the source locations in the region of interest that map to
6218 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006219 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00006220
6221 // FIXME: We use a ridiculous stack size here because the data-recursion
6222 // algorithm uses a large stack frame than the non-data recursive version,
6223 // and AnnotationTokensWorker currently transforms the data-recursion
6224 // algorithm back into a traditional recursion by explicitly calling
6225 // VisitChildren(). We will need to remove this explicit recursive call.
6226 W.AnnotateTokens();
6227
6228 // If we ran into any entities that involve context-sensitive keywords,
6229 // take another pass through the tokens to mark them as such.
6230 if (W.hasContextSensitiveKeywords()) {
6231 for (unsigned I = 0; I != NumTokens; ++I) {
6232 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
6233 continue;
6234
6235 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
6236 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006237 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006238 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
6239 if (Property->getPropertyAttributesAsWritten() != 0 &&
6240 llvm::StringSwitch<bool>(II->getName())
6241 .Case("readonly", true)
6242 .Case("assign", true)
6243 .Case("unsafe_unretained", true)
6244 .Case("readwrite", true)
6245 .Case("retain", true)
6246 .Case("copy", true)
6247 .Case("nonatomic", true)
6248 .Case("atomic", true)
6249 .Case("getter", true)
6250 .Case("setter", true)
6251 .Case("strong", true)
6252 .Case("weak", true)
6253 .Default(false))
6254 Tokens[I].int_data[0] = CXToken_Keyword;
6255 }
6256 continue;
6257 }
6258
6259 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6260 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6261 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6262 if (llvm::StringSwitch<bool>(II->getName())
6263 .Case("in", true)
6264 .Case("out", true)
6265 .Case("inout", true)
6266 .Case("oneway", true)
6267 .Case("bycopy", true)
6268 .Case("byref", true)
6269 .Default(false))
6270 Tokens[I].int_data[0] = CXToken_Keyword;
6271 continue;
6272 }
6273
6274 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6275 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6276 Tokens[I].int_data[0] = CXToken_Keyword;
6277 continue;
6278 }
6279 }
6280 }
6281}
6282
6283extern "C" {
6284
6285void clang_annotateTokens(CXTranslationUnit TU,
6286 CXToken *Tokens, unsigned NumTokens,
6287 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006288 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006289 LOG_BAD_TU(TU);
6290 return;
6291 }
6292 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006293 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006294 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006295 }
6296
6297 LOG_FUNC_SECTION {
6298 *Log << TU << ' ';
6299 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6300 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6301 *Log << clang_getRange(bloc, eloc);
6302 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006303
6304 // Any token we don't specifically annotate will have a NULL cursor.
6305 CXCursor C = clang_getNullCursor();
6306 for (unsigned I = 0; I != NumTokens; ++I)
6307 Cursors[I] = C;
6308
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006309 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006310 if (!CXXUnit)
6311 return;
6312
6313 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
6314
6315 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
6316 llvm::CrashRecoveryContext CRC;
6317 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
6318 GetSafetyThreadStackSize() * 2)) {
6319 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6320 }
6321}
6322
6323} // end: extern "C"
6324
6325//===----------------------------------------------------------------------===//
6326// Operations for querying linkage of a cursor.
6327//===----------------------------------------------------------------------===//
6328
6329extern "C" {
6330CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6331 if (!clang_isDeclaration(cursor.kind))
6332 return CXLinkage_Invalid;
6333
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006334 const Decl *D = cxcursor::getCursorDecl(cursor);
6335 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006336 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006337 case NoLinkage:
6338 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006339 case InternalLinkage: return CXLinkage_Internal;
6340 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6341 case ExternalLinkage: return CXLinkage_External;
6342 };
6343
6344 return CXLinkage_Invalid;
6345}
6346} // end: extern "C"
6347
6348//===----------------------------------------------------------------------===//
6349// Operations for querying language of a cursor.
6350//===----------------------------------------------------------------------===//
6351
6352static CXLanguageKind getDeclLanguage(const Decl *D) {
6353 if (!D)
6354 return CXLanguage_C;
6355
6356 switch (D->getKind()) {
6357 default:
6358 break;
6359 case Decl::ImplicitParam:
6360 case Decl::ObjCAtDefsField:
6361 case Decl::ObjCCategory:
6362 case Decl::ObjCCategoryImpl:
6363 case Decl::ObjCCompatibleAlias:
6364 case Decl::ObjCImplementation:
6365 case Decl::ObjCInterface:
6366 case Decl::ObjCIvar:
6367 case Decl::ObjCMethod:
6368 case Decl::ObjCProperty:
6369 case Decl::ObjCPropertyImpl:
6370 case Decl::ObjCProtocol:
Douglas Gregor85f3f952015-07-07 03:57:15 +00006371 case Decl::ObjCTypeParam:
Guy Benyei11169dd2012-12-18 14:30:41 +00006372 return CXLanguage_ObjC;
6373 case Decl::CXXConstructor:
6374 case Decl::CXXConversion:
6375 case Decl::CXXDestructor:
6376 case Decl::CXXMethod:
6377 case Decl::CXXRecord:
6378 case Decl::ClassTemplate:
6379 case Decl::ClassTemplatePartialSpecialization:
6380 case Decl::ClassTemplateSpecialization:
6381 case Decl::Friend:
6382 case Decl::FriendTemplate:
6383 case Decl::FunctionTemplate:
6384 case Decl::LinkageSpec:
6385 case Decl::Namespace:
6386 case Decl::NamespaceAlias:
6387 case Decl::NonTypeTemplateParm:
6388 case Decl::StaticAssert:
6389 case Decl::TemplateTemplateParm:
6390 case Decl::TemplateTypeParm:
6391 case Decl::UnresolvedUsingTypename:
6392 case Decl::UnresolvedUsingValue:
6393 case Decl::Using:
6394 case Decl::UsingDirective:
6395 case Decl::UsingShadow:
6396 return CXLanguage_CPlusPlus;
6397 }
6398
6399 return CXLanguage_C;
6400}
6401
6402extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006403
6404static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6405 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
6406 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00006407
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006408 switch (D->getAvailability()) {
6409 case AR_Available:
6410 case AR_NotYetIntroduced:
6411 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006412 return getCursorAvailabilityForDecl(
6413 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006414 return CXAvailability_Available;
6415
6416 case AR_Deprecated:
6417 return CXAvailability_Deprecated;
6418
6419 case AR_Unavailable:
6420 return CXAvailability_NotAvailable;
6421 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006422
6423 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006424}
6425
Guy Benyei11169dd2012-12-18 14:30:41 +00006426enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6427 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006428 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6429 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006430
6431 return CXAvailability_Available;
6432}
6433
6434static CXVersion convertVersion(VersionTuple In) {
6435 CXVersion Out = { -1, -1, -1 };
6436 if (In.empty())
6437 return Out;
6438
6439 Out.Major = In.getMajor();
6440
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006441 Optional<unsigned> Minor = In.getMinor();
6442 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006443 Out.Minor = *Minor;
6444 else
6445 return Out;
6446
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006447 Optional<unsigned> Subminor = In.getSubminor();
6448 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006449 Out.Subminor = *Subminor;
6450
6451 return Out;
6452}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006453
6454static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6455 int *always_deprecated,
6456 CXString *deprecated_message,
6457 int *always_unavailable,
6458 CXString *unavailable_message,
6459 CXPlatformAvailability *availability,
6460 int availability_size) {
6461 bool HadAvailAttr = false;
6462 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006463 for (auto A : D->attrs()) {
6464 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006465 HadAvailAttr = true;
6466 if (always_deprecated)
6467 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006468 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006469 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006470 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006471 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006472 continue;
6473 }
6474
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006475 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006476 HadAvailAttr = true;
6477 if (always_unavailable)
6478 *always_unavailable = 1;
6479 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006480 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006481 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6482 }
6483 continue;
6484 }
6485
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006486 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006487 HadAvailAttr = true;
6488 if (N < availability_size) {
6489 availability[N].Platform
6490 = cxstring::createDup(Avail->getPlatform()->getName());
6491 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6492 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6493 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6494 availability[N].Unavailable = Avail->getUnavailable();
6495 availability[N].Message = cxstring::createDup(Avail->getMessage());
6496 }
6497 ++N;
6498 }
6499 }
6500
6501 if (!HadAvailAttr)
6502 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6503 return getCursorPlatformAvailabilityForDecl(
6504 cast<Decl>(EnumConst->getDeclContext()),
6505 always_deprecated,
6506 deprecated_message,
6507 always_unavailable,
6508 unavailable_message,
6509 availability,
6510 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006511
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006512 return N;
6513}
6514
Guy Benyei11169dd2012-12-18 14:30:41 +00006515int clang_getCursorPlatformAvailability(CXCursor cursor,
6516 int *always_deprecated,
6517 CXString *deprecated_message,
6518 int *always_unavailable,
6519 CXString *unavailable_message,
6520 CXPlatformAvailability *availability,
6521 int availability_size) {
6522 if (always_deprecated)
6523 *always_deprecated = 0;
6524 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006525 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006526 if (always_unavailable)
6527 *always_unavailable = 0;
6528 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006529 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006530
Guy Benyei11169dd2012-12-18 14:30:41 +00006531 if (!clang_isDeclaration(cursor.kind))
6532 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006533
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006534 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006535 if (!D)
6536 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006537
6538 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6539 deprecated_message,
6540 always_unavailable,
6541 unavailable_message,
6542 availability,
6543 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006544}
6545
6546void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6547 clang_disposeString(availability->Platform);
6548 clang_disposeString(availability->Message);
6549}
6550
6551CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6552 if (clang_isDeclaration(cursor.kind))
6553 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6554
6555 return CXLanguage_Invalid;
6556}
6557
6558 /// \brief If the given cursor is the "templated" declaration
6559 /// descibing a class or function template, return the class or
6560 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006561static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006562 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006563 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006564
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006565 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006566 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6567 return FunTmpl;
6568
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006569 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006570 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6571 return ClassTmpl;
6572
6573 return D;
6574}
6575
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006576
6577enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
6578 StorageClass sc = SC_None;
6579 const Decl *D = getCursorDecl(C);
6580 if (D) {
6581 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
6582 sc = FD->getStorageClass();
6583 } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
6584 sc = VD->getStorageClass();
6585 } else {
6586 return CX_SC_Invalid;
6587 }
6588 } else {
6589 return CX_SC_Invalid;
6590 }
6591 switch (sc) {
6592 case SC_None:
6593 return CX_SC_None;
6594 case SC_Extern:
6595 return CX_SC_Extern;
6596 case SC_Static:
6597 return CX_SC_Static;
6598 case SC_PrivateExtern:
6599 return CX_SC_PrivateExtern;
6600 case SC_OpenCLWorkGroupLocal:
6601 return CX_SC_OpenCLWorkGroupLocal;
6602 case SC_Auto:
6603 return CX_SC_Auto;
6604 case SC_Register:
6605 return CX_SC_Register;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006606 }
Kaelyn Takataab61e702014-10-15 18:03:26 +00006607 llvm_unreachable("Unhandled storage class!");
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006608}
6609
Guy Benyei11169dd2012-12-18 14:30:41 +00006610CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6611 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006612 if (const Decl *D = getCursorDecl(cursor)) {
6613 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006614 if (!DC)
6615 return clang_getNullCursor();
6616
6617 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6618 getCursorTU(cursor));
6619 }
6620 }
6621
6622 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006623 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006624 return MakeCXCursor(D, getCursorTU(cursor));
6625 }
6626
6627 return clang_getNullCursor();
6628}
6629
6630CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6631 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006632 if (const Decl *D = getCursorDecl(cursor)) {
6633 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006634 if (!DC)
6635 return clang_getNullCursor();
6636
6637 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6638 getCursorTU(cursor));
6639 }
6640 }
6641
6642 // FIXME: Note that we can't easily compute the lexical context of a
6643 // statement or expression, so we return nothing.
6644 return clang_getNullCursor();
6645}
6646
6647CXFile clang_getIncludedFile(CXCursor cursor) {
6648 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006649 return nullptr;
6650
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006651 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006652 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006653}
6654
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006655unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6656 if (C.kind != CXCursor_ObjCPropertyDecl)
6657 return CXObjCPropertyAttr_noattr;
6658
6659 unsigned Result = CXObjCPropertyAttr_noattr;
6660 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6661 ObjCPropertyDecl::PropertyAttributeKind Attr =
6662 PD->getPropertyAttributesAsWritten();
6663
6664#define SET_CXOBJCPROP_ATTR(A) \
6665 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6666 Result |= CXObjCPropertyAttr_##A
6667 SET_CXOBJCPROP_ATTR(readonly);
6668 SET_CXOBJCPROP_ATTR(getter);
6669 SET_CXOBJCPROP_ATTR(assign);
6670 SET_CXOBJCPROP_ATTR(readwrite);
6671 SET_CXOBJCPROP_ATTR(retain);
6672 SET_CXOBJCPROP_ATTR(copy);
6673 SET_CXOBJCPROP_ATTR(nonatomic);
6674 SET_CXOBJCPROP_ATTR(setter);
6675 SET_CXOBJCPROP_ATTR(atomic);
6676 SET_CXOBJCPROP_ATTR(weak);
6677 SET_CXOBJCPROP_ATTR(strong);
6678 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6679#undef SET_CXOBJCPROP_ATTR
6680
6681 return Result;
6682}
6683
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006684unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6685 if (!clang_isDeclaration(C.kind))
6686 return CXObjCDeclQualifier_None;
6687
6688 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6689 const Decl *D = getCursorDecl(C);
6690 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6691 QT = MD->getObjCDeclQualifier();
6692 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6693 QT = PD->getObjCDeclQualifier();
6694 if (QT == Decl::OBJC_TQ_None)
6695 return CXObjCDeclQualifier_None;
6696
6697 unsigned Result = CXObjCDeclQualifier_None;
6698 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6699 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6700 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6701 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6702 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6703 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6704
6705 return Result;
6706}
6707
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006708unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6709 if (!clang_isDeclaration(C.kind))
6710 return 0;
6711
6712 const Decl *D = getCursorDecl(C);
6713 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6714 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6715 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6716 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6717
6718 return 0;
6719}
6720
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006721unsigned clang_Cursor_isVariadic(CXCursor C) {
6722 if (!clang_isDeclaration(C.kind))
6723 return 0;
6724
6725 const Decl *D = getCursorDecl(C);
6726 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6727 return FD->isVariadic();
6728 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6729 return MD->isVariadic();
6730
6731 return 0;
6732}
6733
Guy Benyei11169dd2012-12-18 14:30:41 +00006734CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6735 if (!clang_isDeclaration(C.kind))
6736 return clang_getNullRange();
6737
6738 const Decl *D = getCursorDecl(C);
6739 ASTContext &Context = getCursorContext(C);
6740 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6741 if (!RC)
6742 return clang_getNullRange();
6743
6744 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6745}
6746
6747CXString clang_Cursor_getRawCommentText(CXCursor C) {
6748 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006749 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006750
6751 const Decl *D = getCursorDecl(C);
6752 ASTContext &Context = getCursorContext(C);
6753 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6754 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6755 StringRef();
6756
6757 // Don't duplicate the string because RawText points directly into source
6758 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006759 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006760}
6761
6762CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6763 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006764 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006765
6766 const Decl *D = getCursorDecl(C);
6767 const ASTContext &Context = getCursorContext(C);
6768 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6769
6770 if (RC) {
6771 StringRef BriefText = RC->getBriefText(Context);
6772
6773 // Don't duplicate the string because RawComment ensures that this memory
6774 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006775 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006776 }
6777
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006778 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006779}
6780
Guy Benyei11169dd2012-12-18 14:30:41 +00006781CXModule clang_Cursor_getModule(CXCursor C) {
6782 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006783 if (const ImportDecl *ImportD =
6784 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006785 return ImportD->getImportedModule();
6786 }
6787
Craig Topper69186e72014-06-08 08:38:04 +00006788 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006789}
6790
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006791CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6792 if (isNotUsableTU(TU)) {
6793 LOG_BAD_TU(TU);
6794 return nullptr;
6795 }
6796 if (!File)
6797 return nullptr;
6798 FileEntry *FE = static_cast<FileEntry *>(File);
6799
6800 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6801 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6802 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6803
Richard Smithfeb54b62014-10-23 02:01:19 +00006804 return Header.getModule();
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006805}
6806
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006807CXFile clang_Module_getASTFile(CXModule CXMod) {
6808 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006809 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006810 Module *Mod = static_cast<Module*>(CXMod);
6811 return const_cast<FileEntry *>(Mod->getASTFile());
6812}
6813
Guy Benyei11169dd2012-12-18 14:30:41 +00006814CXModule clang_Module_getParent(CXModule CXMod) {
6815 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006816 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006817 Module *Mod = static_cast<Module*>(CXMod);
6818 return Mod->Parent;
6819}
6820
6821CXString clang_Module_getName(CXModule CXMod) {
6822 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006823 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006824 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006825 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006826}
6827
6828CXString clang_Module_getFullName(CXModule CXMod) {
6829 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006830 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006831 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006832 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006833}
6834
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006835int clang_Module_isSystem(CXModule CXMod) {
6836 if (!CXMod)
6837 return 0;
6838 Module *Mod = static_cast<Module*>(CXMod);
6839 return Mod->IsSystem;
6840}
6841
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006842unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6843 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006844 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006845 LOG_BAD_TU(TU);
6846 return 0;
6847 }
6848 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006849 return 0;
6850 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006851 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6852 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6853 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006854}
6855
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006856CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6857 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006858 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006859 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006860 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006861 }
6862 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006863 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006864 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006865 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006866
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006867 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6868 if (Index < TopHeaders.size())
6869 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006870
Craig Topper69186e72014-06-08 08:38:04 +00006871 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006872}
6873
6874} // end: extern "C"
6875
6876//===----------------------------------------------------------------------===//
6877// C++ AST instrospection.
6878//===----------------------------------------------------------------------===//
6879
6880extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006881unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6882 if (!clang_isDeclaration(C.kind))
6883 return 0;
6884
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006885 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006886 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006887 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006888 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6889}
6890
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006891unsigned clang_CXXMethod_isConst(CXCursor C) {
6892 if (!clang_isDeclaration(C.kind))
6893 return 0;
6894
6895 const Decl *D = cxcursor::getCursorDecl(C);
6896 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006897 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006898 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6899}
6900
Guy Benyei11169dd2012-12-18 14:30:41 +00006901unsigned clang_CXXMethod_isStatic(CXCursor C) {
6902 if (!clang_isDeclaration(C.kind))
6903 return 0;
6904
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006905 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006906 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006907 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006908 return (Method && Method->isStatic()) ? 1 : 0;
6909}
6910
6911unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6912 if (!clang_isDeclaration(C.kind))
6913 return 0;
6914
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006915 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006916 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006917 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006918 return (Method && Method->isVirtual()) ? 1 : 0;
6919}
6920} // end: extern "C"
6921
6922//===----------------------------------------------------------------------===//
6923// Attribute introspection.
6924//===----------------------------------------------------------------------===//
6925
6926extern "C" {
6927CXType clang_getIBOutletCollectionType(CXCursor C) {
6928 if (C.kind != CXCursor_IBOutletCollectionAttr)
6929 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6930
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006931 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006932 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6933
6934 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6935}
6936} // end: extern "C"
6937
6938//===----------------------------------------------------------------------===//
6939// Inspecting memory usage.
6940//===----------------------------------------------------------------------===//
6941
6942typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6943
6944static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6945 enum CXTUResourceUsageKind k,
6946 unsigned long amount) {
6947 CXTUResourceUsageEntry entry = { k, amount };
6948 entries.push_back(entry);
6949}
6950
6951extern "C" {
6952
6953const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6954 const char *str = "";
6955 switch (kind) {
6956 case CXTUResourceUsage_AST:
6957 str = "ASTContext: expressions, declarations, and types";
6958 break;
6959 case CXTUResourceUsage_Identifiers:
6960 str = "ASTContext: identifiers";
6961 break;
6962 case CXTUResourceUsage_Selectors:
6963 str = "ASTContext: selectors";
6964 break;
6965 case CXTUResourceUsage_GlobalCompletionResults:
6966 str = "Code completion: cached global results";
6967 break;
6968 case CXTUResourceUsage_SourceManagerContentCache:
6969 str = "SourceManager: content cache allocator";
6970 break;
6971 case CXTUResourceUsage_AST_SideTables:
6972 str = "ASTContext: side tables";
6973 break;
6974 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6975 str = "SourceManager: malloc'ed memory buffers";
6976 break;
6977 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6978 str = "SourceManager: mmap'ed memory buffers";
6979 break;
6980 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6981 str = "ExternalASTSource: malloc'ed memory buffers";
6982 break;
6983 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6984 str = "ExternalASTSource: mmap'ed memory buffers";
6985 break;
6986 case CXTUResourceUsage_Preprocessor:
6987 str = "Preprocessor: malloc'ed memory";
6988 break;
6989 case CXTUResourceUsage_PreprocessingRecord:
6990 str = "Preprocessor: PreprocessingRecord";
6991 break;
6992 case CXTUResourceUsage_SourceManager_DataStructures:
6993 str = "SourceManager: data structures and tables";
6994 break;
6995 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6996 str = "Preprocessor: header search tables";
6997 break;
6998 }
6999 return str;
7000}
7001
7002CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007003 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007004 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00007005 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00007006 return usage;
7007 }
7008
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007009 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00007010 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00007011 ASTContext &astContext = astUnit->getASTContext();
7012
7013 // How much memory is used by AST nodes and types?
7014 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
7015 (unsigned long) astContext.getASTAllocatedMemory());
7016
7017 // How much memory is used by identifiers?
7018 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
7019 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
7020
7021 // How much memory is used for selectors?
7022 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
7023 (unsigned long) astContext.Selectors.getTotalMemory());
7024
7025 // How much memory is used by ASTContext's side tables?
7026 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
7027 (unsigned long) astContext.getSideTableAllocatedMemory());
7028
7029 // How much memory is used for caching global code completion results?
7030 unsigned long completionBytes = 0;
7031 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00007032 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007033 completionBytes = completionAllocator->getTotalMemory();
7034 }
7035 createCXTUResourceUsageEntry(*entries,
7036 CXTUResourceUsage_GlobalCompletionResults,
7037 completionBytes);
7038
7039 // How much memory is being used by SourceManager's content cache?
7040 createCXTUResourceUsageEntry(*entries,
7041 CXTUResourceUsage_SourceManagerContentCache,
7042 (unsigned long) astContext.getSourceManager().getContentCacheSize());
7043
7044 // How much memory is being used by the MemoryBuffer's in SourceManager?
7045 const SourceManager::MemoryBufferSizes &srcBufs =
7046 astUnit->getSourceManager().getMemoryBufferSizes();
7047
7048 createCXTUResourceUsageEntry(*entries,
7049 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
7050 (unsigned long) srcBufs.malloc_bytes);
7051 createCXTUResourceUsageEntry(*entries,
7052 CXTUResourceUsage_SourceManager_Membuffer_MMap,
7053 (unsigned long) srcBufs.mmap_bytes);
7054 createCXTUResourceUsageEntry(*entries,
7055 CXTUResourceUsage_SourceManager_DataStructures,
7056 (unsigned long) astContext.getSourceManager()
7057 .getDataStructureSizes());
7058
7059 // How much memory is being used by the ExternalASTSource?
7060 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
7061 const ExternalASTSource::MemoryBufferSizes &sizes =
7062 esrc->getMemoryBufferSizes();
7063
7064 createCXTUResourceUsageEntry(*entries,
7065 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
7066 (unsigned long) sizes.malloc_bytes);
7067 createCXTUResourceUsageEntry(*entries,
7068 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
7069 (unsigned long) sizes.mmap_bytes);
7070 }
7071
7072 // How much memory is being used by the Preprocessor?
7073 Preprocessor &pp = astUnit->getPreprocessor();
7074 createCXTUResourceUsageEntry(*entries,
7075 CXTUResourceUsage_Preprocessor,
7076 pp.getTotalMemory());
7077
7078 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
7079 createCXTUResourceUsageEntry(*entries,
7080 CXTUResourceUsage_PreprocessingRecord,
7081 pRec->getTotalMemory());
7082 }
7083
7084 createCXTUResourceUsageEntry(*entries,
7085 CXTUResourceUsage_Preprocessor_HeaderSearch,
7086 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00007087
Guy Benyei11169dd2012-12-18 14:30:41 +00007088 CXTUResourceUsage usage = { (void*) entries.get(),
7089 (unsigned) entries->size(),
Alexander Kornienko6ee521c2015-01-23 15:36:10 +00007090 !entries->empty() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00007091 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00007092 return usage;
7093}
7094
7095void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
7096 if (usage.data)
7097 delete (MemUsageEntries*) usage.data;
7098}
7099
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007100CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
7101 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007102 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00007103 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007104
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007105 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007106 LOG_BAD_TU(TU);
7107 return skipped;
7108 }
7109
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007110 if (!file)
7111 return skipped;
7112
7113 ASTUnit *astUnit = cxtu::getASTUnit(TU);
7114 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
7115 if (!ppRec)
7116 return skipped;
7117
7118 ASTContext &Ctx = astUnit->getASTContext();
7119 SourceManager &sm = Ctx.getSourceManager();
7120 FileEntry *fileEntry = static_cast<FileEntry *>(file);
7121 FileID wantedFileID = sm.translateFile(fileEntry);
7122
7123 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
7124 std::vector<SourceRange> wantedRanges;
7125 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
7126 i != ei; ++i) {
7127 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
7128 wantedRanges.push_back(*i);
7129 }
7130
7131 skipped->count = wantedRanges.size();
7132 skipped->ranges = new CXSourceRange[skipped->count];
7133 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
7134 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
7135
7136 return skipped;
7137}
7138
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007139void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
7140 if (ranges) {
7141 delete[] ranges->ranges;
7142 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007143 }
7144}
7145
Guy Benyei11169dd2012-12-18 14:30:41 +00007146} // end extern "C"
7147
7148void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
7149 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
7150 for (unsigned I = 0; I != Usage.numEntries; ++I)
7151 fprintf(stderr, " %s: %lu\n",
7152 clang_getTUResourceUsageName(Usage.entries[I].kind),
7153 Usage.entries[I].amount);
7154
7155 clang_disposeCXTUResourceUsage(Usage);
7156}
7157
7158//===----------------------------------------------------------------------===//
7159// Misc. utility functions.
7160//===----------------------------------------------------------------------===//
7161
7162/// Default to using an 8 MB stack size on "safety" threads.
7163static unsigned SafetyStackThreadSize = 8 << 20;
7164
7165namespace clang {
7166
7167bool RunSafely(llvm::CrashRecoveryContext &CRC,
7168 void (*Fn)(void*), void *UserData,
7169 unsigned Size) {
7170 if (!Size)
7171 Size = GetSafetyThreadStackSize();
7172 if (Size)
7173 return CRC.RunSafelyOnThread(Fn, UserData, Size);
7174 return CRC.RunSafely(Fn, UserData);
7175}
7176
7177unsigned GetSafetyThreadStackSize() {
7178 return SafetyStackThreadSize;
7179}
7180
7181void SetSafetyThreadStackSize(unsigned Value) {
7182 SafetyStackThreadSize = Value;
7183}
7184
Alexander Kornienkoab9db512015-06-22 23:07:51 +00007185}
Guy Benyei11169dd2012-12-18 14:30:41 +00007186
7187void clang::setThreadBackgroundPriority() {
7188 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
7189 return;
7190
Alp Toker1a86ad22014-07-06 06:24:00 +00007191#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00007192 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
7193#endif
7194}
7195
7196void cxindex::printDiagsToStderr(ASTUnit *Unit) {
7197 if (!Unit)
7198 return;
7199
7200 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
7201 DEnd = Unit->stored_diag_end();
7202 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00007203 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00007204 CXString Msg = clang_formatDiagnostic(&Diag,
7205 clang_defaultDiagnosticDisplayOptions());
7206 fprintf(stderr, "%s\n", clang_getCString(Msg));
7207 clang_disposeString(Msg);
7208 }
7209#ifdef LLVM_ON_WIN32
7210 // On Windows, force a flush, since there may be multiple copies of
7211 // stderr and stdout in the file system, all with different buffers
7212 // but writing to the same device.
7213 fflush(stderr);
7214#endif
7215}
7216
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007217MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
7218 SourceLocation MacroDefLoc,
7219 CXTranslationUnit TU){
7220 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007221 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007222 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007223 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007224
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007225 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007226 Preprocessor &PP = Unit->getPreprocessor();
Richard Smith20e883e2015-04-29 23:20:19 +00007227 MacroDirective *MD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007228 if (MD) {
7229 for (MacroDirective::DefInfo
7230 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
7231 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
7232 return Def.getMacroInfo();
7233 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007234 }
7235
Craig Topper69186e72014-06-08 08:38:04 +00007236 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007237}
7238
Richard Smith66a81862015-05-04 02:25:31 +00007239const MacroInfo *cxindex::getMacroInfo(const MacroDefinitionRecord *MacroDef,
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007240 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007241 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007242 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007243 const IdentifierInfo *II = MacroDef->getName();
7244 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00007245 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007246
7247 return getMacroInfo(*II, MacroDef->getLocation(), TU);
7248}
7249
Richard Smith66a81862015-05-04 02:25:31 +00007250MacroDefinitionRecord *
7251cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, const Token &Tok,
7252 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007253 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007254 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007255 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00007256 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007257
7258 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007259 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007260 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
7261 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007262 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007263
7264 // Check that the token is inside the definition and not its argument list.
7265 SourceManager &SM = Unit->getSourceManager();
7266 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00007267 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007268 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00007269 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007270
7271 Preprocessor &PP = Unit->getPreprocessor();
7272 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
7273 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00007274 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007275
Alp Toker2d57cea2014-05-17 04:53:25 +00007276 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007277 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007278 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007279
7280 // Check that the identifier is not one of the macro arguments.
7281 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00007282 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007283
Richard Smith20e883e2015-04-29 23:20:19 +00007284 MacroDirective *InnerMD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007285 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00007286 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007287
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007288 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007289}
7290
Richard Smith66a81862015-05-04 02:25:31 +00007291MacroDefinitionRecord *
7292cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, SourceLocation Loc,
7293 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007294 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007295 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007296
7297 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007298 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007299 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007300 Preprocessor &PP = Unit->getPreprocessor();
7301 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00007302 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007303 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7304 Token Tok;
7305 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00007306 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007307
7308 return checkForMacroInMacroDefinition(MI, Tok, TU);
7309}
7310
Guy Benyei11169dd2012-12-18 14:30:41 +00007311extern "C" {
7312
7313CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007314 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00007315}
7316
7317} // end: extern "C"
7318
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007319Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7320 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007321 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007322 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007323 if (Unit->isMainFileAST())
7324 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007325 return *this;
7326 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007327 } else {
7328 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007329 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007330 return *this;
7331}
7332
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007333Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7334 *this << FE->getName();
7335 return *this;
7336}
7337
7338Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7339 CXString cursorName = clang_getCursorDisplayName(cursor);
7340 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7341 clang_disposeString(cursorName);
7342 return *this;
7343}
7344
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007345Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7346 CXFile File;
7347 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007348 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007349 CXString FileName = clang_getFileName(File);
7350 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7351 clang_disposeString(FileName);
7352 return *this;
7353}
7354
7355Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7356 CXSourceLocation BLoc = clang_getRangeStart(range);
7357 CXSourceLocation ELoc = clang_getRangeEnd(range);
7358
7359 CXFile BFile;
7360 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007361 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007362
7363 CXFile EFile;
7364 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007365 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007366
7367 CXString BFileName = clang_getFileName(BFile);
7368 if (BFile == EFile) {
7369 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7370 BLine, BColumn, ELine, EColumn);
7371 } else {
7372 CXString EFileName = clang_getFileName(EFile);
7373 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7374 BLine, BColumn)
7375 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7376 ELine, EColumn);
7377 clang_disposeString(EFileName);
7378 }
7379 clang_disposeString(BFileName);
7380 return *this;
7381}
7382
7383Logger &cxindex::Logger::operator<<(CXString Str) {
7384 *this << clang_getCString(Str);
7385 return *this;
7386}
7387
7388Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7389 LogOS << Fmt;
7390 return *this;
7391}
7392
Chandler Carruth37ad2582014-06-27 15:14:39 +00007393static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7394
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007395cxindex::Logger::~Logger() {
7396 LogOS.flush();
7397
Chandler Carruth37ad2582014-06-27 15:14:39 +00007398 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007399
7400 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7401
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007402 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007403 OS << "[libclang:" << Name << ':';
7404
Alp Toker1a86ad22014-07-06 06:24:00 +00007405#ifdef USE_DARWIN_THREADS
7406 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007407 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7408 OS << tid << ':';
7409#endif
7410
7411 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7412 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
Yaron Keren09fb7c62015-03-10 07:33:23 +00007413 OS << Msg << '\n';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007414
7415 if (Trace) {
Zachary Turner1fe2a8d2015-03-05 19:15:09 +00007416 llvm::sys::PrintStackTrace(OS);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007417 OS << "--------------------------------------------------\n";
7418 }
7419}