blob: 3579fc77c77a5d85cc6db0531b03e8d5bb39f372 [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"
Adrian Prantlbc068582015-07-08 01:00:30 +000032#include "clang/CodeGen/ObjectFilePCHContainerOperations.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000033#include "clang/Frontend/ASTUnit.h"
34#include "clang/Frontend/CompilerInstance.h"
35#include "clang/Frontend/FrontendDiagnostic.h"
Dmitri Gribenko9e605112013-11-13 22:16:51 +000036#include "clang/Index/CommentToXML.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000037#include "clang/Lex/HeaderSearch.h"
38#include "clang/Lex/Lexer.h"
39#include "clang/Lex/PreprocessingRecord.h"
40#include "clang/Lex/Preprocessor.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000041#include "clang/Serialization/SerializationDiagnostic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000042#include "llvm/ADT/Optional.h"
43#include "llvm/ADT/STLExtras.h"
44#include "llvm/ADT/StringSwitch.h"
Alp Toker1d257e12014-06-04 03:28:55 +000045#include "llvm/Config/llvm-config.h"
Eli Bendersky79759592014-08-01 15:01:10 +000046#include "llvm/IR/DataLayout.h"
47#include "llvm/IR/Mangler.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000048#include "llvm/Support/Compiler.h"
49#include "llvm/Support/CrashRecoveryContext.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000050#include "llvm/Support/Format.h"
Chandler Carruth37ad2582014-06-27 15:14:39 +000051#include "llvm/Support/ManagedStatic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000052#include "llvm/Support/MemoryBuffer.h"
53#include "llvm/Support/Mutex.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000054#include "llvm/Support/Program.h"
55#include "llvm/Support/SaveAndRestore.h"
56#include "llvm/Support/Signals.h"
Adrian Prantlbc068582015-07-08 01:00:30 +000057#include "llvm/Support/TargetSelect.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000058#include "llvm/Support/Threading.h"
59#include "llvm/Support/Timer.h"
60#include "llvm/Support/raw_ostream.h"
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000061
Alp Toker1a86ad22014-07-06 06:24:00 +000062#if LLVM_ENABLE_THREADS != 0 && defined(__APPLE__)
63#define USE_DARWIN_THREADS
64#endif
65
66#ifdef USE_DARWIN_THREADS
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000067#include <pthread.h>
68#endif
Guy Benyei11169dd2012-12-18 14:30:41 +000069
70using namespace clang;
71using namespace clang::cxcursor;
Guy Benyei11169dd2012-12-18 14:30:41 +000072using namespace clang::cxtu;
73using namespace clang::cxindex;
74
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000075CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) {
76 if (!AU)
Craig Topper69186e72014-06-08 08:38:04 +000077 return nullptr;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000078 assert(CIdx);
Guy Benyei11169dd2012-12-18 14:30:41 +000079 CXTranslationUnit D = new CXTranslationUnitImpl();
80 D->CIdx = CIdx;
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000081 D->TheASTUnit = AU;
Dmitri Gribenko74895212013-02-03 13:52:47 +000082 D->StringPool = new cxstring::CXStringPool();
Craig Topper69186e72014-06-08 08:38:04 +000083 D->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000084 D->OverridenCursorsPool = createOverridenCXCursorsPool();
Craig Topper69186e72014-06-08 08:38:04 +000085 D->CommentToXML = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000086 return D;
87}
88
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000089bool cxtu::isASTReadError(ASTUnit *AU) {
90 for (ASTUnit::stored_diag_iterator D = AU->stored_diag_begin(),
91 DEnd = AU->stored_diag_end();
92 D != DEnd; ++D) {
93 if (D->getLevel() >= DiagnosticsEngine::Error &&
94 DiagnosticIDs::getCategoryNumberForDiag(D->getID()) ==
95 diag::DiagCat_AST_Deserialization_Issue)
96 return true;
97 }
98 return false;
99}
100
Guy Benyei11169dd2012-12-18 14:30:41 +0000101cxtu::CXTUOwner::~CXTUOwner() {
102 if (TU)
103 clang_disposeTranslationUnit(TU);
104}
105
106/// \brief Compare two source ranges to determine their relative position in
107/// the translation unit.
108static RangeComparisonResult RangeCompare(SourceManager &SM,
109 SourceRange R1,
110 SourceRange R2) {
111 assert(R1.isValid() && "First range is invalid?");
112 assert(R2.isValid() && "Second range is invalid?");
113 if (R1.getEnd() != R2.getBegin() &&
114 SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
115 return RangeBefore;
116 if (R2.getEnd() != R1.getBegin() &&
117 SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
118 return RangeAfter;
119 return RangeOverlap;
120}
121
122/// \brief Determine if a source location falls within, before, or after a
123/// a given source range.
124static RangeComparisonResult LocationCompare(SourceManager &SM,
125 SourceLocation L, SourceRange R) {
126 assert(R.isValid() && "First range is invalid?");
127 assert(L.isValid() && "Second range is invalid?");
128 if (L == R.getBegin() || L == R.getEnd())
129 return RangeOverlap;
130 if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
131 return RangeBefore;
132 if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
133 return RangeAfter;
134 return RangeOverlap;
135}
136
137/// \brief Translate a Clang source range into a CIndex source range.
138///
139/// Clang internally represents ranges where the end location points to the
140/// start of the token at the end. However, for external clients it is more
141/// useful to have a CXSourceRange be a proper half-open interval. This routine
142/// does the appropriate translation.
143CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
144 const LangOptions &LangOpts,
145 const CharSourceRange &R) {
146 // We want the last character in this location, so we will adjust the
147 // location accordingly.
148 SourceLocation EndLoc = R.getEnd();
149 if (EndLoc.isValid() && EndLoc.isMacroID() && !SM.isMacroArgExpansion(EndLoc))
150 EndLoc = SM.getExpansionRange(EndLoc).second;
151 if (R.isTokenRange() && !EndLoc.isInvalid()) {
152 unsigned Length = Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc),
153 SM, LangOpts);
154 EndLoc = EndLoc.getLocWithOffset(Length);
155 }
156
Bill Wendlingeade3622013-01-23 08:25:41 +0000157 CXSourceRange Result = {
Dmitri Gribenkof9304482013-01-23 15:56:07 +0000158 { &SM, &LangOpts },
Bill Wendlingeade3622013-01-23 08:25:41 +0000159 R.getBegin().getRawEncoding(),
160 EndLoc.getRawEncoding()
161 };
Guy Benyei11169dd2012-12-18 14:30:41 +0000162 return Result;
163}
164
165//===----------------------------------------------------------------------===//
166// Cursor visitor.
167//===----------------------------------------------------------------------===//
168
169static SourceRange getRawCursorExtent(CXCursor C);
170static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
171
172
173RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
174 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
175}
176
177/// \brief Visit the given cursor and, if requested by the visitor,
178/// its children.
179///
180/// \param Cursor the cursor to visit.
181///
182/// \param CheckedRegionOfInterest if true, then the caller already checked
183/// that this cursor is within the region of interest.
184///
185/// \returns true if the visitation should be aborted, false if it
186/// should continue.
187bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
188 if (clang_isInvalid(Cursor.kind))
189 return false;
190
191 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000192 const Decl *D = getCursorDecl(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000193 if (!D) {
194 assert(0 && "Invalid declaration cursor");
195 return true; // abort.
196 }
197
198 // Ignore implicit declarations, unless it's an objc method because
199 // currently we should report implicit methods for properties when indexing.
200 if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
201 return false;
202 }
203
204 // If we have a range of interest, and this cursor doesn't intersect with it,
205 // we're done.
206 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
207 SourceRange Range = getRawCursorExtent(Cursor);
208 if (Range.isInvalid() || CompareRegionOfInterest(Range))
209 return false;
210 }
211
212 switch (Visitor(Cursor, Parent, ClientData)) {
213 case CXChildVisit_Break:
214 return true;
215
216 case CXChildVisit_Continue:
217 return false;
218
219 case CXChildVisit_Recurse: {
220 bool ret = VisitChildren(Cursor);
221 if (PostChildrenVisitor)
222 if (PostChildrenVisitor(Cursor, ClientData))
223 return true;
224 return ret;
225 }
226 }
227
228 llvm_unreachable("Invalid CXChildVisitResult!");
229}
230
231static bool visitPreprocessedEntitiesInRange(SourceRange R,
232 PreprocessingRecord &PPRec,
233 CursorVisitor &Visitor) {
234 SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
235 FileID FID;
236
237 if (!Visitor.shouldVisitIncludedEntities()) {
238 // If the begin/end of the range lie in the same FileID, do the optimization
239 // where we skip preprocessed entities that do not come from the same FileID.
240 FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
241 if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
242 FID = FileID();
243 }
244
Benjamin Kramerb4ef6682015-02-06 17:25:10 +0000245 const auto &Entities = PPRec.getPreprocessedEntitiesInRange(R);
246 return Visitor.visitPreprocessedEntities(Entities.begin(), Entities.end(),
Guy Benyei11169dd2012-12-18 14:30:41 +0000247 PPRec, FID);
248}
249
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000250bool CursorVisitor::visitFileRegion() {
Guy Benyei11169dd2012-12-18 14:30:41 +0000251 if (RegionOfInterest.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000252 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000253
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000254 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000255 SourceManager &SM = Unit->getSourceManager();
256
257 std::pair<FileID, unsigned>
258 Begin = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getBegin())),
259 End = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getEnd()));
260
261 if (End.first != Begin.first) {
262 // If the end does not reside in the same file, try to recover by
263 // picking the end of the file of begin location.
264 End.first = Begin.first;
265 End.second = SM.getFileIDSize(Begin.first);
266 }
267
268 assert(Begin.first == End.first);
269 if (Begin.second > End.second)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000270 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000271
272 FileID File = Begin.first;
273 unsigned Offset = Begin.second;
274 unsigned Length = End.second - Begin.second;
275
276 if (!VisitDeclsOnly && !VisitPreprocessorLast)
277 if (visitPreprocessedEntitiesInRegion())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000278 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000279
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000280 if (visitDeclsFromFileRegion(File, Offset, Length))
281 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000282
283 if (!VisitDeclsOnly && VisitPreprocessorLast)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000284 return visitPreprocessedEntitiesInRegion();
285
286 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000287}
288
289static bool isInLexicalContext(Decl *D, DeclContext *DC) {
290 if (!DC)
291 return false;
292
293 for (DeclContext *DeclDC = D->getLexicalDeclContext();
294 DeclDC; DeclDC = DeclDC->getLexicalParent()) {
295 if (DeclDC == DC)
296 return true;
297 }
298 return false;
299}
300
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000301bool CursorVisitor::visitDeclsFromFileRegion(FileID File,
Guy Benyei11169dd2012-12-18 14:30:41 +0000302 unsigned Offset, unsigned Length) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000303 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000304 SourceManager &SM = Unit->getSourceManager();
305 SourceRange Range = RegionOfInterest;
306
307 SmallVector<Decl *, 16> Decls;
308 Unit->findFileRegionDecls(File, Offset, Length, Decls);
309
310 // If we didn't find any file level decls for the file, try looking at the
311 // file that it was included from.
312 while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
313 bool Invalid = false;
314 const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
315 if (Invalid)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000316 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000317
318 SourceLocation Outer;
319 if (SLEntry.isFile())
320 Outer = SLEntry.getFile().getIncludeLoc();
321 else
322 Outer = SLEntry.getExpansion().getExpansionLocStart();
323 if (Outer.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000324 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000325
Benjamin Kramer867ea1d2014-03-02 13:01:17 +0000326 std::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
Guy Benyei11169dd2012-12-18 14:30:41 +0000327 Length = 0;
328 Unit->findFileRegionDecls(File, Offset, Length, Decls);
329 }
330
331 assert(!Decls.empty());
332
333 bool VisitedAtLeastOnce = false;
Craig Topper69186e72014-06-08 08:38:04 +0000334 DeclContext *CurDC = nullptr;
Craig Topper2341c0d2013-07-04 03:08:24 +0000335 SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
336 for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000337 Decl *D = *DIt;
338 if (D->getSourceRange().isInvalid())
339 continue;
340
341 if (isInLexicalContext(D, CurDC))
342 continue;
343
344 CurDC = dyn_cast<DeclContext>(D);
345
346 if (TagDecl *TD = dyn_cast<TagDecl>(D))
347 if (!TD->isFreeStanding())
348 continue;
349
350 RangeComparisonResult CompRes = RangeCompare(SM, D->getSourceRange(),Range);
351 if (CompRes == RangeBefore)
352 continue;
353 if (CompRes == RangeAfter)
354 break;
355
356 assert(CompRes == RangeOverlap);
357 VisitedAtLeastOnce = true;
358
359 if (isa<ObjCContainerDecl>(D)) {
360 FileDI_current = &DIt;
361 FileDE_current = DE;
362 } else {
Craig Topper69186e72014-06-08 08:38:04 +0000363 FileDI_current = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +0000364 }
365
366 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000367 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000368 }
369
370 if (VisitedAtLeastOnce)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000371 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000372
373 // No Decls overlapped with the range. Move up the lexical context until there
374 // is a context that contains the range or we reach the translation unit
375 // level.
376 DeclContext *DC = DIt == Decls.begin() ? (*DIt)->getLexicalDeclContext()
377 : (*(DIt-1))->getLexicalDeclContext();
378
379 while (DC && !DC->isTranslationUnit()) {
380 Decl *D = cast<Decl>(DC);
381 SourceRange CurDeclRange = D->getSourceRange();
382 if (CurDeclRange.isInvalid())
383 break;
384
385 if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000386 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
387 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000388 }
389
390 DC = D->getLexicalDeclContext();
391 }
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000392
393 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000394}
395
396bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
397 if (!AU->getPreprocessor().getPreprocessingRecord())
398 return false;
399
400 PreprocessingRecord &PPRec
401 = *AU->getPreprocessor().getPreprocessingRecord();
402 SourceManager &SM = AU->getSourceManager();
403
404 if (RegionOfInterest.isValid()) {
405 SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
406 SourceLocation B = MappedRange.getBegin();
407 SourceLocation E = MappedRange.getEnd();
408
409 if (AU->isInPreambleFileID(B)) {
410 if (SM.isLoadedSourceLocation(E))
411 return visitPreprocessedEntitiesInRange(SourceRange(B, E),
412 PPRec, *this);
413
414 // Beginning of range lies in the preamble but it also extends beyond
415 // it into the main file. Split the range into 2 parts, one covering
416 // the preamble and another covering the main file. This allows subsequent
417 // calls to visitPreprocessedEntitiesInRange to accept a source range that
418 // lies in the same FileID, allowing it to skip preprocessed entities that
419 // do not come from the same FileID.
420 bool breaked =
421 visitPreprocessedEntitiesInRange(
422 SourceRange(B, AU->getEndOfPreambleFileID()),
423 PPRec, *this);
424 if (breaked) return true;
425 return visitPreprocessedEntitiesInRange(
426 SourceRange(AU->getStartOfMainFileID(), E),
427 PPRec, *this);
428 }
429
430 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
431 }
432
433 bool OnlyLocalDecls
434 = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
435
436 if (OnlyLocalDecls)
437 return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
438 PPRec);
439
440 return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
441}
442
443template<typename InputIterator>
444bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
445 InputIterator Last,
446 PreprocessingRecord &PPRec,
447 FileID FID) {
448 for (; First != Last; ++First) {
449 if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
450 continue;
451
452 PreprocessedEntity *PPE = *First;
Argyrios Kyrtzidis1030f262013-05-07 20:37:17 +0000453 if (!PPE)
454 continue;
455
Guy Benyei11169dd2012-12-18 14:30:41 +0000456 if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
457 if (Visit(MakeMacroExpansionCursor(ME, TU)))
458 return true;
Richard Smith66a81862015-05-04 02:25:31 +0000459
Guy Benyei11169dd2012-12-18 14:30:41 +0000460 continue;
461 }
Richard Smith66a81862015-05-04 02:25:31 +0000462
463 if (MacroDefinitionRecord *MD = dyn_cast<MacroDefinitionRecord>(PPE)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000464 if (Visit(MakeMacroDefinitionCursor(MD, TU)))
465 return true;
Richard Smith66a81862015-05-04 02:25:31 +0000466
Guy Benyei11169dd2012-12-18 14:30:41 +0000467 continue;
468 }
469
470 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
471 if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
472 return true;
473
474 continue;
475 }
476 }
477
478 return false;
479}
480
481/// \brief Visit the children of the given cursor.
482///
483/// \returns true if the visitation should be aborted, false if it
484/// should continue.
485bool CursorVisitor::VisitChildren(CXCursor Cursor) {
486 if (clang_isReference(Cursor.kind) &&
487 Cursor.kind != CXCursor_CXXBaseSpecifier) {
488 // By definition, references have no children.
489 return false;
490 }
491
492 // Set the Parent field to Cursor, then back to its old value once we're
493 // done.
494 SetParentRAII SetParent(Parent, StmtParent, Cursor);
495
496 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000497 Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +0000498 if (!D)
499 return false;
500
501 return VisitAttributes(D) || Visit(D);
502 }
503
504 if (clang_isStatement(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000505 if (const Stmt *S = getCursorStmt(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000506 return Visit(S);
507
508 return false;
509 }
510
511 if (clang_isExpression(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000512 if (const Expr *E = getCursorExpr(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000513 return Visit(E);
514
515 return false;
516 }
517
518 if (clang_isTranslationUnit(Cursor.kind)) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000519 CXTranslationUnit TU = getCursorTU(Cursor);
520 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000521
522 int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
523 for (unsigned I = 0; I != 2; ++I) {
524 if (VisitOrder[I]) {
525 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
526 RegionOfInterest.isInvalid()) {
527 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
528 TLEnd = CXXUnit->top_level_end();
529 TL != TLEnd; ++TL) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000530 if (Visit(MakeCXCursor(*TL, TU, RegionOfInterest), true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000531 return true;
532 }
533 } else if (VisitDeclContext(
534 CXXUnit->getASTContext().getTranslationUnitDecl()))
535 return true;
536 continue;
537 }
538
539 // Walk the preprocessing record.
540 if (CXXUnit->getPreprocessor().getPreprocessingRecord())
541 visitPreprocessedEntitiesInRegion();
542 }
543
544 return false;
545 }
546
547 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000548 if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000549 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
550 return Visit(BaseTSInfo->getTypeLoc());
551 }
552 }
553 }
554
555 if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +0000556 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +0000557 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
Richard Smithb1f9a282013-10-31 01:56:18 +0000558 if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())
Richard Smithb87c4652013-10-31 21:23:20 +0000559 return Visit(cxcursor::MakeCursorObjCClassRef(
560 ObjT->getInterface(),
561 A->getInterfaceLoc()->getTypeLoc().getLocStart(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +0000562 }
563
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000564 // If pointing inside a macro definition, check if the token is an identifier
565 // that was ever defined as a macro. In such a case, create a "pseudo" macro
566 // expansion cursor for that token.
567 SourceLocation BeginLoc = RegionOfInterest.getBegin();
568 if (Cursor.kind == CXCursor_MacroDefinition &&
569 BeginLoc == RegionOfInterest.getEnd()) {
570 SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000571 const MacroInfo *MI =
572 getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
Richard Smith66a81862015-05-04 02:25:31 +0000573 if (MacroDefinitionRecord *MacroDef =
574 checkForMacroInMacroDefinition(MI, Loc, TU))
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000575 return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
576 }
577
Guy Benyei11169dd2012-12-18 14:30:41 +0000578 // Nothing to visit at the moment.
579 return false;
580}
581
582bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
583 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
584 if (Visit(TSInfo->getTypeLoc()))
585 return true;
586
587 if (Stmt *Body = B->getBody())
588 return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
589
590 return false;
591}
592
Ted Kremenek03325582013-02-21 01:29:01 +0000593Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000594 if (RegionOfInterest.isValid()) {
595 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
596 if (Range.isInvalid())
David Blaikie7a30dc52013-02-21 01:47:18 +0000597 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000598
599 switch (CompareRegionOfInterest(Range)) {
600 case RangeBefore:
601 // This declaration comes before the region of interest; skip it.
David Blaikie7a30dc52013-02-21 01:47:18 +0000602 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000603
604 case RangeAfter:
605 // This declaration comes after the region of interest; we're done.
606 return false;
607
608 case RangeOverlap:
609 // This declaration overlaps the region of interest; visit it.
610 break;
611 }
612 }
613 return true;
614}
615
616bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
617 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
618
619 // FIXME: Eventually remove. This part of a hack to support proper
620 // iteration over all Decls contained lexically within an ObjC container.
621 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
622 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
623
624 for ( ; I != E; ++I) {
625 Decl *D = *I;
626 if (D->getLexicalDeclContext() != DC)
627 continue;
628 CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
629
630 // Ignore synthesized ivars here, otherwise if we have something like:
631 // @synthesize prop = _prop;
632 // and '_prop' is not declared, we will encounter a '_prop' ivar before
633 // encountering the 'prop' synthesize declaration and we will think that
634 // we passed the region-of-interest.
635 if (ObjCIvarDecl *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
636 if (ivarD->getSynthesize())
637 continue;
638 }
639
640 // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
641 // declarations is a mismatch with the compiler semantics.
642 if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
643 ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
644 if (!ID->isThisDeclarationADefinition())
645 Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
646
647 } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
648 ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
649 if (!PD->isThisDeclarationADefinition())
650 Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
651 }
652
Ted Kremenek03325582013-02-21 01:29:01 +0000653 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000654 if (!V.hasValue())
655 continue;
656 if (!V.getValue())
657 return false;
658 if (Visit(Cursor, true))
659 return true;
660 }
661 return false;
662}
663
664bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
665 llvm_unreachable("Translation units are visited directly by Visit()");
666}
667
668bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
669 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
670 return Visit(TSInfo->getTypeLoc());
671
672 return false;
673}
674
675bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
676 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
677 return Visit(TSInfo->getTypeLoc());
678
679 return false;
680}
681
682bool CursorVisitor::VisitTagDecl(TagDecl *D) {
683 return VisitDeclContext(D);
684}
685
686bool CursorVisitor::VisitClassTemplateSpecializationDecl(
687 ClassTemplateSpecializationDecl *D) {
688 bool ShouldVisitBody = false;
689 switch (D->getSpecializationKind()) {
690 case TSK_Undeclared:
691 case TSK_ImplicitInstantiation:
692 // Nothing to visit
693 return false;
694
695 case TSK_ExplicitInstantiationDeclaration:
696 case TSK_ExplicitInstantiationDefinition:
697 break;
698
699 case TSK_ExplicitSpecialization:
700 ShouldVisitBody = true;
701 break;
702 }
703
704 // Visit the template arguments used in the specialization.
705 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
706 TypeLoc TL = SpecType->getTypeLoc();
David Blaikie6adc78e2013-02-18 22:06:02 +0000707 if (TemplateSpecializationTypeLoc TSTLoc =
708 TL.getAs<TemplateSpecializationTypeLoc>()) {
709 for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
710 if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000711 return true;
712 }
713 }
714
715 if (ShouldVisitBody && VisitCXXRecordDecl(D))
716 return true;
717
718 return false;
719}
720
721bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
722 ClassTemplatePartialSpecializationDecl *D) {
723 // FIXME: Visit the "outer" template parameter lists on the TagDecl
724 // before visiting these template parameters.
725 if (VisitTemplateParameters(D->getTemplateParameters()))
726 return true;
727
728 // Visit the partial specialization arguments.
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000729 const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
730 const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
731 for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
Guy Benyei11169dd2012-12-18 14:30:41 +0000732 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
733 return true;
734
735 return VisitCXXRecordDecl(D);
736}
737
738bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
739 // Visit the default argument.
740 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
741 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
742 if (Visit(DefArg->getTypeLoc()))
743 return true;
744
745 return false;
746}
747
748bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
749 if (Expr *Init = D->getInitExpr())
750 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
751 return false;
752}
753
754bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000755 unsigned NumParamList = DD->getNumTemplateParameterLists();
756 for (unsigned i = 0; i < NumParamList; i++) {
757 TemplateParameterList* Params = DD->getTemplateParameterList(i);
758 if (VisitTemplateParameters(Params))
759 return true;
760 }
761
Guy Benyei11169dd2012-12-18 14:30:41 +0000762 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
763 if (Visit(TSInfo->getTypeLoc()))
764 return true;
765
766 // Visit the nested-name-specifier, if present.
767 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
768 if (VisitNestedNameSpecifierLoc(QualifierLoc))
769 return true;
770
771 return false;
772}
773
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000774/// \brief Compare two base or member initializers based on their source order.
775static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
776 CXXCtorInitializer *const *Y) {
777 return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
778}
779
Guy Benyei11169dd2012-12-18 14:30:41 +0000780bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000781 unsigned NumParamList = ND->getNumTemplateParameterLists();
782 for (unsigned i = 0; i < NumParamList; i++) {
783 TemplateParameterList* Params = ND->getTemplateParameterList(i);
784 if (VisitTemplateParameters(Params))
785 return true;
786 }
787
Guy Benyei11169dd2012-12-18 14:30:41 +0000788 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
789 // Visit the function declaration's syntactic components in the order
790 // written. This requires a bit of work.
791 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
David Blaikie6adc78e2013-02-18 22:06:02 +0000792 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Guy Benyei11169dd2012-12-18 14:30:41 +0000793
794 // If we have a function declared directly (without the use of a typedef),
795 // visit just the return type. Otherwise, just visit the function's type
796 // now.
Alp Toker42a16a62014-01-25 23:51:36 +0000797 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getReturnLoc())) ||
Guy Benyei11169dd2012-12-18 14:30:41 +0000798 (!FTL && Visit(TL)))
799 return true;
800
801 // Visit the nested-name-specifier, if present.
802 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
803 if (VisitNestedNameSpecifierLoc(QualifierLoc))
804 return true;
805
806 // Visit the declaration name.
Argyrios Kyrtzidis4a4d2b42014-02-09 08:13:47 +0000807 if (!isa<CXXDestructorDecl>(ND))
808 if (VisitDeclarationNameInfo(ND->getNameInfo()))
809 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +0000810
811 // FIXME: Visit explicitly-specified template arguments!
812
813 // Visit the function parameters, if we have a function type.
David Blaikie6adc78e2013-02-18 22:06:02 +0000814 if (FTL && VisitFunctionTypeLoc(FTL, true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000815 return true;
816
Bill Wendling44426052012-12-20 19:22:21 +0000817 // FIXME: Attributes?
Guy Benyei11169dd2012-12-18 14:30:41 +0000818 }
819
820 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
821 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
822 // Find the initializers that were written in the source.
823 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
Aaron Ballman0ad78302014-03-13 17:34:31 +0000824 for (auto *I : Constructor->inits()) {
825 if (!I->isWritten())
Guy Benyei11169dd2012-12-18 14:30:41 +0000826 continue;
827
Aaron Ballman0ad78302014-03-13 17:34:31 +0000828 WrittenInits.push_back(I);
Guy Benyei11169dd2012-12-18 14:30:41 +0000829 }
830
831 // Sort the initializers in source order
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000832 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
833 &CompareCXXCtorInitializers);
834
Guy Benyei11169dd2012-12-18 14:30:41 +0000835 // Visit the initializers in source order
836 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
837 CXXCtorInitializer *Init = WrittenInits[I];
838 if (Init->isAnyMemberInitializer()) {
839 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
840 Init->getMemberLocation(), TU)))
841 return true;
842 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
843 if (Visit(TInfo->getTypeLoc()))
844 return true;
845 }
846
847 // Visit the initializer value.
848 if (Expr *Initializer = Init->getInit())
849 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
850 return true;
851 }
852 }
853
854 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
855 return true;
856 }
857
858 return false;
859}
860
861bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
862 if (VisitDeclaratorDecl(D))
863 return true;
864
865 if (Expr *BitWidth = D->getBitWidth())
866 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
867
868 return false;
869}
870
871bool CursorVisitor::VisitVarDecl(VarDecl *D) {
872 if (VisitDeclaratorDecl(D))
873 return true;
874
875 if (Expr *Init = D->getInit())
876 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
877
878 return false;
879}
880
881bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
882 if (VisitDeclaratorDecl(D))
883 return true;
884
885 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
886 if (Expr *DefArg = D->getDefaultArgument())
887 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
888
889 return false;
890}
891
892bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
893 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
894 // before visiting these template parameters.
895 if (VisitTemplateParameters(D->getTemplateParameters()))
896 return true;
897
898 return VisitFunctionDecl(D->getTemplatedDecl());
899}
900
901bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
902 // FIXME: Visit the "outer" template parameter lists on the TagDecl
903 // before visiting these template parameters.
904 if (VisitTemplateParameters(D->getTemplateParameters()))
905 return true;
906
907 return VisitCXXRecordDecl(D->getTemplatedDecl());
908}
909
910bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
911 if (VisitTemplateParameters(D->getTemplateParameters()))
912 return true;
913
914 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
915 VisitTemplateArgumentLoc(D->getDefaultArgument()))
916 return true;
917
918 return false;
919}
920
Douglas Gregor9bda6cf2015-07-07 03:58:14 +0000921bool CursorVisitor::VisitObjCTypeParamDecl(ObjCTypeParamDecl *D) {
922 // Visit the bound, if it's explicit.
923 if (D->hasExplicitBound()) {
924 if (auto TInfo = D->getTypeSourceInfo()) {
925 if (Visit(TInfo->getTypeLoc()))
926 return true;
927 }
928 }
929
930 return false;
931}
932
Guy Benyei11169dd2012-12-18 14:30:41 +0000933bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Alp Toker314cc812014-01-25 16:55:45 +0000934 if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
Guy Benyei11169dd2012-12-18 14:30:41 +0000935 if (Visit(TSInfo->getTypeLoc()))
936 return true;
937
Aaron Ballman43b68be2014-03-07 17:50:17 +0000938 for (const auto *P : ND->params()) {
939 if (Visit(MakeCXCursor(P, TU, RegionOfInterest)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000940 return true;
941 }
942
943 if (ND->isThisDeclarationADefinition() &&
944 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
945 return true;
946
947 return false;
948}
949
950template <typename DeclIt>
951static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
952 SourceManager &SM, SourceLocation EndLoc,
953 SmallVectorImpl<Decl *> &Decls) {
954 DeclIt next = *DI_current;
955 while (++next != DE_current) {
956 Decl *D_next = *next;
957 if (!D_next)
958 break;
959 SourceLocation L = D_next->getLocStart();
960 if (!L.isValid())
961 break;
962 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
963 *DI_current = next;
964 Decls.push_back(D_next);
965 continue;
966 }
967 break;
968 }
969}
970
Guy Benyei11169dd2012-12-18 14:30:41 +0000971bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
972 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
973 // an @implementation can lexically contain Decls that are not properly
974 // nested in the AST. When we identify such cases, we need to retrofit
975 // this nesting here.
976 if (!DI_current && !FileDI_current)
977 return VisitDeclContext(D);
978
979 // Scan the Decls that immediately come after the container
980 // in the current DeclContext. If any fall within the
981 // container's lexical region, stash them into a vector
982 // for later processing.
983 SmallVector<Decl *, 24> DeclsInContainer;
984 SourceLocation EndLoc = D->getSourceRange().getEnd();
985 SourceManager &SM = AU->getSourceManager();
986 if (EndLoc.isValid()) {
987 if (DI_current) {
988 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
989 DeclsInContainer);
990 } else {
991 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
992 DeclsInContainer);
993 }
994 }
995
996 // The common case.
997 if (DeclsInContainer.empty())
998 return VisitDeclContext(D);
999
1000 // Get all the Decls in the DeclContext, and sort them with the
1001 // additional ones we've collected. Then visit them.
Aaron Ballman629afae2014-03-07 19:56:05 +00001002 for (auto *SubDecl : D->decls()) {
1003 if (!SubDecl || SubDecl->getLexicalDeclContext() != D ||
1004 SubDecl->getLocStart().isInvalid())
Guy Benyei11169dd2012-12-18 14:30:41 +00001005 continue;
Aaron Ballman629afae2014-03-07 19:56:05 +00001006 DeclsInContainer.push_back(SubDecl);
Guy Benyei11169dd2012-12-18 14:30:41 +00001007 }
1008
1009 // Now sort the Decls so that they appear in lexical order.
1010 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
Benjamin Kramerbbdd7642014-03-01 14:48:57 +00001011 [&SM](Decl *A, Decl *B) {
1012 SourceLocation L_A = A->getLocStart();
1013 SourceLocation L_B = B->getLocStart();
1014 assert(L_A.isValid() && L_B.isValid());
1015 return SM.isBeforeInTranslationUnit(L_A, L_B);
1016 });
Guy Benyei11169dd2012-12-18 14:30:41 +00001017
1018 // Now visit the decls.
1019 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
1020 E = DeclsInContainer.end(); I != E; ++I) {
1021 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek03325582013-02-21 01:29:01 +00001022 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00001023 if (!V.hasValue())
1024 continue;
1025 if (!V.getValue())
1026 return false;
1027 if (Visit(Cursor, true))
1028 return true;
1029 }
1030 return false;
1031}
1032
1033bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1034 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1035 TU)))
1036 return true;
1037
Douglas Gregore9d95f12015-07-07 03:57:35 +00001038 if (VisitObjCTypeParamList(ND->getTypeParamList()))
1039 return true;
1040
Guy Benyei11169dd2012-12-18 14:30:41 +00001041 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1042 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1043 E = ND->protocol_end(); I != E; ++I, ++PL)
1044 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1045 return true;
1046
1047 return VisitObjCContainerDecl(ND);
1048}
1049
1050bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1051 if (!PID->isThisDeclarationADefinition())
1052 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1053
1054 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1055 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1056 E = PID->protocol_end(); I != E; ++I, ++PL)
1057 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1058 return true;
1059
1060 return VisitObjCContainerDecl(PID);
1061}
1062
1063bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1064 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1065 return true;
1066
1067 // FIXME: This implements a workaround with @property declarations also being
1068 // installed in the DeclContext for the @interface. Eventually this code
1069 // should be removed.
1070 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1071 if (!CDecl || !CDecl->IsClassExtension())
1072 return false;
1073
1074 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1075 if (!ID)
1076 return false;
1077
1078 IdentifierInfo *PropertyId = PD->getIdentifier();
1079 ObjCPropertyDecl *prevDecl =
1080 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1081
1082 if (!prevDecl)
1083 return false;
1084
1085 // Visit synthesized methods since they will be skipped when visiting
1086 // the @interface.
1087 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1088 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1089 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1090 return true;
1091
1092 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1093 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1094 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1095 return true;
1096
1097 return false;
1098}
1099
Douglas Gregore9d95f12015-07-07 03:57:35 +00001100bool CursorVisitor::VisitObjCTypeParamList(ObjCTypeParamList *typeParamList) {
1101 if (!typeParamList)
1102 return false;
1103
1104 for (auto *typeParam : *typeParamList) {
1105 // Visit the type parameter.
1106 if (Visit(MakeCXCursor(typeParam, TU, RegionOfInterest)))
1107 return true;
Douglas Gregore9d95f12015-07-07 03:57:35 +00001108 }
1109
1110 return false;
1111}
1112
Guy Benyei11169dd2012-12-18 14:30:41 +00001113bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1114 if (!D->isThisDeclarationADefinition()) {
1115 // Forward declaration is treated like a reference.
1116 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1117 }
1118
Douglas Gregore9d95f12015-07-07 03:57:35 +00001119 // Objective-C type parameters.
1120 if (VisitObjCTypeParamList(D->getTypeParamListAsWritten()))
1121 return true;
1122
Guy Benyei11169dd2012-12-18 14:30:41 +00001123 // Issue callbacks for super class.
1124 if (D->getSuperClass() &&
1125 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1126 D->getSuperClassLoc(),
1127 TU)))
1128 return true;
1129
Douglas Gregore9d95f12015-07-07 03:57:35 +00001130 if (TypeSourceInfo *SuperClassTInfo = D->getSuperClassTInfo())
1131 if (Visit(SuperClassTInfo->getTypeLoc()))
1132 return true;
1133
Guy Benyei11169dd2012-12-18 14:30:41 +00001134 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1135 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1136 E = D->protocol_end(); I != E; ++I, ++PL)
1137 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1138 return true;
1139
1140 return VisitObjCContainerDecl(D);
1141}
1142
1143bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1144 return VisitObjCContainerDecl(D);
1145}
1146
1147bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1148 // 'ID' could be null when dealing with invalid code.
1149 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1150 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1151 return true;
1152
1153 return VisitObjCImplDecl(D);
1154}
1155
1156bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1157#if 0
1158 // Issue callbacks for super class.
1159 // FIXME: No source location information!
1160 if (D->getSuperClass() &&
1161 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1162 D->getSuperClassLoc(),
1163 TU)))
1164 return true;
1165#endif
1166
1167 return VisitObjCImplDecl(D);
1168}
1169
1170bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1171 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1172 if (PD->isIvarNameSpecified())
1173 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1174
1175 return false;
1176}
1177
1178bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1179 return VisitDeclContext(D);
1180}
1181
1182bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1183 // Visit nested-name-specifier.
1184 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1185 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1186 return true;
1187
1188 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1189 D->getTargetNameLoc(), TU));
1190}
1191
1192bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1193 // Visit nested-name-specifier.
1194 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1195 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1196 return true;
1197 }
1198
1199 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1200 return true;
1201
1202 return VisitDeclarationNameInfo(D->getNameInfo());
1203}
1204
1205bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1206 // Visit nested-name-specifier.
1207 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1208 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1209 return true;
1210
1211 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1212 D->getIdentLocation(), TU));
1213}
1214
1215bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1216 // Visit nested-name-specifier.
1217 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1218 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1219 return true;
1220 }
1221
1222 return VisitDeclarationNameInfo(D->getNameInfo());
1223}
1224
1225bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1226 UnresolvedUsingTypenameDecl *D) {
1227 // Visit nested-name-specifier.
1228 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1229 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1230 return true;
1231
1232 return false;
1233}
1234
1235bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1236 switch (Name.getName().getNameKind()) {
1237 case clang::DeclarationName::Identifier:
1238 case clang::DeclarationName::CXXLiteralOperatorName:
1239 case clang::DeclarationName::CXXOperatorName:
1240 case clang::DeclarationName::CXXUsingDirective:
1241 return false;
1242
1243 case clang::DeclarationName::CXXConstructorName:
1244 case clang::DeclarationName::CXXDestructorName:
1245 case clang::DeclarationName::CXXConversionFunctionName:
1246 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1247 return Visit(TSInfo->getTypeLoc());
1248 return false;
1249
1250 case clang::DeclarationName::ObjCZeroArgSelector:
1251 case clang::DeclarationName::ObjCOneArgSelector:
1252 case clang::DeclarationName::ObjCMultiArgSelector:
1253 // FIXME: Per-identifier location info?
1254 return false;
1255 }
1256
1257 llvm_unreachable("Invalid DeclarationName::Kind!");
1258}
1259
1260bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1261 SourceRange Range) {
1262 // FIXME: This whole routine is a hack to work around the lack of proper
1263 // source information in nested-name-specifiers (PR5791). Since we do have
1264 // a beginning source location, we can visit the first component of the
1265 // nested-name-specifier, if it's a single-token component.
1266 if (!NNS)
1267 return false;
1268
1269 // Get the first component in the nested-name-specifier.
1270 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1271 NNS = Prefix;
1272
1273 switch (NNS->getKind()) {
1274 case NestedNameSpecifier::Namespace:
1275 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1276 TU));
1277
1278 case NestedNameSpecifier::NamespaceAlias:
1279 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1280 Range.getBegin(), TU));
1281
1282 case NestedNameSpecifier::TypeSpec: {
1283 // If the type has a form where we know that the beginning of the source
1284 // range matches up with a reference cursor. Visit the appropriate reference
1285 // cursor.
1286 const Type *T = NNS->getAsType();
1287 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1288 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1289 if (const TagType *Tag = dyn_cast<TagType>(T))
1290 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1291 if (const TemplateSpecializationType *TST
1292 = dyn_cast<TemplateSpecializationType>(T))
1293 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1294 break;
1295 }
1296
1297 case NestedNameSpecifier::TypeSpecWithTemplate:
1298 case NestedNameSpecifier::Global:
1299 case NestedNameSpecifier::Identifier:
Nikola Smiljanic67860242014-09-26 00:28:20 +00001300 case NestedNameSpecifier::Super:
Guy Benyei11169dd2012-12-18 14:30:41 +00001301 break;
1302 }
1303
1304 return false;
1305}
1306
1307bool
1308CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1309 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1310 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1311 Qualifiers.push_back(Qualifier);
1312
1313 while (!Qualifiers.empty()) {
1314 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1315 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1316 switch (NNS->getKind()) {
1317 case NestedNameSpecifier::Namespace:
1318 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1319 Q.getLocalBeginLoc(),
1320 TU)))
1321 return true;
1322
1323 break;
1324
1325 case NestedNameSpecifier::NamespaceAlias:
1326 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1327 Q.getLocalBeginLoc(),
1328 TU)))
1329 return true;
1330
1331 break;
1332
1333 case NestedNameSpecifier::TypeSpec:
1334 case NestedNameSpecifier::TypeSpecWithTemplate:
1335 if (Visit(Q.getTypeLoc()))
1336 return true;
1337
1338 break;
1339
1340 case NestedNameSpecifier::Global:
1341 case NestedNameSpecifier::Identifier:
Nikola Smiljanic67860242014-09-26 00:28:20 +00001342 case NestedNameSpecifier::Super:
Guy Benyei11169dd2012-12-18 14:30:41 +00001343 break;
1344 }
1345 }
1346
1347 return false;
1348}
1349
1350bool CursorVisitor::VisitTemplateParameters(
1351 const TemplateParameterList *Params) {
1352 if (!Params)
1353 return false;
1354
1355 for (TemplateParameterList::const_iterator P = Params->begin(),
1356 PEnd = Params->end();
1357 P != PEnd; ++P) {
1358 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1359 return true;
1360 }
1361
1362 return false;
1363}
1364
1365bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1366 switch (Name.getKind()) {
1367 case TemplateName::Template:
1368 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1369
1370 case TemplateName::OverloadedTemplate:
1371 // Visit the overloaded template set.
1372 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1373 return true;
1374
1375 return false;
1376
1377 case TemplateName::DependentTemplate:
1378 // FIXME: Visit nested-name-specifier.
1379 return false;
1380
1381 case TemplateName::QualifiedTemplate:
1382 // FIXME: Visit nested-name-specifier.
1383 return Visit(MakeCursorTemplateRef(
1384 Name.getAsQualifiedTemplateName()->getDecl(),
1385 Loc, TU));
1386
1387 case TemplateName::SubstTemplateTemplateParm:
1388 return Visit(MakeCursorTemplateRef(
1389 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1390 Loc, TU));
1391
1392 case TemplateName::SubstTemplateTemplateParmPack:
1393 return Visit(MakeCursorTemplateRef(
1394 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1395 Loc, TU));
1396 }
1397
1398 llvm_unreachable("Invalid TemplateName::Kind!");
1399}
1400
1401bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1402 switch (TAL.getArgument().getKind()) {
1403 case TemplateArgument::Null:
1404 case TemplateArgument::Integral:
1405 case TemplateArgument::Pack:
1406 return false;
1407
1408 case TemplateArgument::Type:
1409 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1410 return Visit(TSInfo->getTypeLoc());
1411 return false;
1412
1413 case TemplateArgument::Declaration:
1414 if (Expr *E = TAL.getSourceDeclExpression())
1415 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1416 return false;
1417
1418 case TemplateArgument::NullPtr:
1419 if (Expr *E = TAL.getSourceNullPtrExpression())
1420 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1421 return false;
1422
1423 case TemplateArgument::Expression:
1424 if (Expr *E = TAL.getSourceExpression())
1425 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1426 return false;
1427
1428 case TemplateArgument::Template:
1429 case TemplateArgument::TemplateExpansion:
1430 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1431 return true;
1432
1433 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1434 TAL.getTemplateNameLoc());
1435 }
1436
1437 llvm_unreachable("Invalid TemplateArgument::Kind!");
1438}
1439
1440bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1441 return VisitDeclContext(D);
1442}
1443
1444bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1445 return Visit(TL.getUnqualifiedLoc());
1446}
1447
1448bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1449 ASTContext &Context = AU->getASTContext();
1450
1451 // Some builtin types (such as Objective-C's "id", "sel", and
1452 // "Class") have associated declarations. Create cursors for those.
1453 QualType VisitType;
1454 switch (TL.getTypePtr()->getKind()) {
1455
1456 case BuiltinType::Void:
1457 case BuiltinType::NullPtr:
1458 case BuiltinType::Dependent:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001459 case BuiltinType::OCLImage1d:
1460 case BuiltinType::OCLImage1dArray:
1461 case BuiltinType::OCLImage1dBuffer:
1462 case BuiltinType::OCLImage2d:
1463 case BuiltinType::OCLImage2dArray:
1464 case BuiltinType::OCLImage3d:
NAKAMURA Takumi288c42e2013-02-07 12:47:42 +00001465 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +00001466 case BuiltinType::OCLEvent:
Guy Benyei11169dd2012-12-18 14:30:41 +00001467#define BUILTIN_TYPE(Id, SingletonId)
1468#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1469#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1470#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1471#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1472#include "clang/AST/BuiltinTypes.def"
1473 break;
1474
1475 case BuiltinType::ObjCId:
1476 VisitType = Context.getObjCIdType();
1477 break;
1478
1479 case BuiltinType::ObjCClass:
1480 VisitType = Context.getObjCClassType();
1481 break;
1482
1483 case BuiltinType::ObjCSel:
1484 VisitType = Context.getObjCSelType();
1485 break;
1486 }
1487
1488 if (!VisitType.isNull()) {
1489 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1490 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1491 TU));
1492 }
1493
1494 return false;
1495}
1496
1497bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1498 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1499}
1500
1501bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1502 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1503}
1504
1505bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1506 if (TL.isDefinition())
1507 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1508
1509 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1510}
1511
1512bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1513 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1514}
1515
1516bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1517 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1518 return true;
1519
1520 return false;
1521}
1522
1523bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1524 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1525 return true;
1526
Douglas Gregore9d95f12015-07-07 03:57:35 +00001527 for (unsigned I = 0, N = TL.getNumTypeArgs(); I != N; ++I) {
1528 if (Visit(TL.getTypeArgTInfo(I)->getTypeLoc()))
1529 return true;
1530 }
1531
Guy Benyei11169dd2012-12-18 14:30:41 +00001532 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1533 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1534 TU)))
1535 return true;
1536 }
1537
1538 return false;
1539}
1540
1541bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1542 return Visit(TL.getPointeeLoc());
1543}
1544
1545bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1546 return Visit(TL.getInnerLoc());
1547}
1548
1549bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1550 return Visit(TL.getPointeeLoc());
1551}
1552
1553bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1554 return Visit(TL.getPointeeLoc());
1555}
1556
1557bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1558 return Visit(TL.getPointeeLoc());
1559}
1560
1561bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1562 return Visit(TL.getPointeeLoc());
1563}
1564
1565bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1566 return Visit(TL.getPointeeLoc());
1567}
1568
1569bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1570 return Visit(TL.getModifiedLoc());
1571}
1572
1573bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1574 bool SkipResultType) {
Alp Toker42a16a62014-01-25 23:51:36 +00001575 if (!SkipResultType && Visit(TL.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001576 return true;
1577
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00001578 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1579 if (Decl *D = TL.getParam(I))
Guy Benyei11169dd2012-12-18 14:30:41 +00001580 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1581 return true;
1582
1583 return false;
1584}
1585
1586bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1587 if (Visit(TL.getElementLoc()))
1588 return true;
1589
1590 if (Expr *Size = TL.getSizeExpr())
1591 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1592
1593 return false;
1594}
1595
Reid Kleckner8a365022013-06-24 17:51:48 +00001596bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1597 return Visit(TL.getOriginalLoc());
1598}
1599
Reid Kleckner0503a872013-12-05 01:23:43 +00001600bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1601 return Visit(TL.getOriginalLoc());
1602}
1603
Guy Benyei11169dd2012-12-18 14:30:41 +00001604bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1605 TemplateSpecializationTypeLoc TL) {
1606 // Visit the template name.
1607 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1608 TL.getTemplateNameLoc()))
1609 return true;
1610
1611 // Visit the template arguments.
1612 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1613 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1614 return true;
1615
1616 return false;
1617}
1618
1619bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1620 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1621}
1622
1623bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1624 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1625 return Visit(TSInfo->getTypeLoc());
1626
1627 return false;
1628}
1629
1630bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1631 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1632 return Visit(TSInfo->getTypeLoc());
1633
1634 return false;
1635}
1636
1637bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1638 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1639 return true;
1640
1641 return false;
1642}
1643
1644bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1645 DependentTemplateSpecializationTypeLoc TL) {
1646 // Visit the nested-name-specifier, if there is one.
1647 if (TL.getQualifierLoc() &&
1648 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1649 return true;
1650
1651 // Visit the template arguments.
1652 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1653 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1654 return true;
1655
1656 return false;
1657}
1658
1659bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1660 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1661 return true;
1662
1663 return Visit(TL.getNamedTypeLoc());
1664}
1665
1666bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1667 return Visit(TL.getPatternLoc());
1668}
1669
1670bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1671 if (Expr *E = TL.getUnderlyingExpr())
1672 return Visit(MakeCXCursor(E, StmtParent, TU));
1673
1674 return false;
1675}
1676
1677bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1678 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1679}
1680
1681bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1682 return Visit(TL.getValueLoc());
1683}
1684
1685#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1686bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1687 return Visit##PARENT##Loc(TL); \
1688}
1689
1690DEFAULT_TYPELOC_IMPL(Complex, Type)
1691DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1692DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1693DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1694DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1695DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1696DEFAULT_TYPELOC_IMPL(Vector, Type)
1697DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1698DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1699DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1700DEFAULT_TYPELOC_IMPL(Record, TagType)
1701DEFAULT_TYPELOC_IMPL(Enum, TagType)
1702DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1703DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1704DEFAULT_TYPELOC_IMPL(Auto, Type)
1705
1706bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1707 // Visit the nested-name-specifier, if present.
1708 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1709 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1710 return true;
1711
1712 if (D->isCompleteDefinition()) {
Aaron Ballman574705e2014-03-13 15:41:46 +00001713 for (const auto &I : D->bases()) {
1714 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001715 return true;
1716 }
1717 }
1718
1719 return VisitTagDecl(D);
1720}
1721
1722bool CursorVisitor::VisitAttributes(Decl *D) {
Aaron Ballmanb97112e2014-03-08 22:19:01 +00001723 for (const auto *I : D->attrs())
1724 if (Visit(MakeCXCursor(I, D, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001725 return true;
1726
1727 return false;
1728}
1729
1730//===----------------------------------------------------------------------===//
1731// Data-recursive visitor methods.
1732//===----------------------------------------------------------------------===//
1733
1734namespace {
1735#define DEF_JOB(NAME, DATA, KIND)\
1736class NAME : public VisitorJob {\
1737public:\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001738 NAME(const DATA *d, CXCursor parent) : \
1739 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei11169dd2012-12-18 14:30:41 +00001740 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001741 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei11169dd2012-12-18 14:30:41 +00001742};
1743
1744DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1745DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1746DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1747DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1748DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1749 ExplicitTemplateArgsVisitKind)
1750DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1751DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1752DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1753#undef DEF_JOB
1754
1755class DeclVisit : public VisitorJob {
1756public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001757 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei11169dd2012-12-18 14:30:41 +00001758 VisitorJob(parent, VisitorJob::DeclVisitKind,
Craig Topper69186e72014-06-08 08:38:04 +00001759 D, isFirst ? (void*) 1 : (void*) nullptr) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001760 static bool classof(const VisitorJob *VJ) {
1761 return VJ->getKind() == DeclVisitKind;
1762 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001763 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Dmitri Gribenkoe5423a72015-03-23 19:23:50 +00001764 bool isFirst() const { return data[1] != nullptr; }
Guy Benyei11169dd2012-12-18 14:30:41 +00001765};
1766class TypeLocVisit : public VisitorJob {
1767public:
1768 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1769 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1770 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1771
1772 static bool classof(const VisitorJob *VJ) {
1773 return VJ->getKind() == TypeLocVisitKind;
1774 }
1775
1776 TypeLoc get() const {
1777 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001778 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001779 }
1780};
1781
1782class LabelRefVisit : public VisitorJob {
1783public:
1784 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1785 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1786 labelLoc.getPtrEncoding()) {}
1787
1788 static bool classof(const VisitorJob *VJ) {
1789 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1790 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001791 const LabelDecl *get() const {
1792 return static_cast<const LabelDecl *>(data[0]);
1793 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001794 SourceLocation getLoc() const {
1795 return SourceLocation::getFromPtrEncoding(data[1]); }
1796};
1797
1798class NestedNameSpecifierLocVisit : public VisitorJob {
1799public:
1800 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1801 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1802 Qualifier.getNestedNameSpecifier(),
1803 Qualifier.getOpaqueData()) { }
1804
1805 static bool classof(const VisitorJob *VJ) {
1806 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1807 }
1808
1809 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001810 return NestedNameSpecifierLoc(
1811 const_cast<NestedNameSpecifier *>(
1812 static_cast<const NestedNameSpecifier *>(data[0])),
1813 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001814 }
1815};
1816
1817class DeclarationNameInfoVisit : public VisitorJob {
1818public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001819 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001820 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001821 static bool classof(const VisitorJob *VJ) {
1822 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1823 }
1824 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001825 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001826 switch (S->getStmtClass()) {
1827 default:
1828 llvm_unreachable("Unhandled Stmt");
1829 case clang::Stmt::MSDependentExistsStmtClass:
1830 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1831 case Stmt::CXXDependentScopeMemberExprClass:
1832 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1833 case Stmt::DependentScopeDeclRefExprClass:
1834 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001835 case Stmt::OMPCriticalDirectiveClass:
1836 return cast<OMPCriticalDirective>(S)->getDirectiveName();
Guy Benyei11169dd2012-12-18 14:30:41 +00001837 }
1838 }
1839};
1840class MemberRefVisit : public VisitorJob {
1841public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001842 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei11169dd2012-12-18 14:30:41 +00001843 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1844 L.getPtrEncoding()) {}
1845 static bool classof(const VisitorJob *VJ) {
1846 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1847 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001848 const FieldDecl *get() const {
1849 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001850 }
1851 SourceLocation getLoc() const {
1852 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1853 }
1854};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001855class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001856 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001857 VisitorWorkList &WL;
1858 CXCursor Parent;
1859public:
1860 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1861 : WL(wl), Parent(parent) {}
1862
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001863 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1864 void VisitBlockExpr(const BlockExpr *B);
1865 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1866 void VisitCompoundStmt(const CompoundStmt *S);
1867 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1868 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1869 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1870 void VisitCXXNewExpr(const CXXNewExpr *E);
1871 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1872 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1873 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1874 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1875 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1876 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1877 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1878 void VisitCXXCatchStmt(const CXXCatchStmt *S);
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00001879 void VisitCXXForRangeStmt(const CXXForRangeStmt *S);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001880 void VisitDeclRefExpr(const DeclRefExpr *D);
1881 void VisitDeclStmt(const DeclStmt *S);
1882 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1883 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1884 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1885 void VisitForStmt(const ForStmt *FS);
1886 void VisitGotoStmt(const GotoStmt *GS);
1887 void VisitIfStmt(const IfStmt *If);
1888 void VisitInitListExpr(const InitListExpr *IE);
1889 void VisitMemberExpr(const MemberExpr *M);
1890 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1891 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1892 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1893 void VisitOverloadExpr(const OverloadExpr *E);
1894 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1895 void VisitStmt(const Stmt *S);
1896 void VisitSwitchStmt(const SwitchStmt *S);
1897 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001898 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1899 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1900 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1901 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1902 void VisitVAArgExpr(const VAArgExpr *E);
1903 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1904 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1905 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1906 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001907 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
Alexander Musman3aaab662014-08-19 11:27:13 +00001908 void VisitOMPLoopDirective(const OMPLoopDirective *D);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001909 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00001910 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00001911 void VisitOMPForDirective(const OMPForDirective *D);
Alexander Musmanf82886e2014-09-18 05:12:34 +00001912 void VisitOMPForSimdDirective(const OMPForSimdDirective *D);
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00001913 void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
Alexey Bataev1e0498a2014-06-26 08:21:58 +00001914 void VisitOMPSectionDirective(const OMPSectionDirective *D);
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00001915 void VisitOMPSingleDirective(const OMPSingleDirective *D);
Alexander Musman80c22892014-07-17 08:54:58 +00001916 void VisitOMPMasterDirective(const OMPMasterDirective *D);
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001917 void VisitOMPCriticalDirective(const OMPCriticalDirective *D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00001918 void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
Alexander Musmane4e893b2014-09-23 09:33:00 +00001919 void VisitOMPParallelForSimdDirective(const OMPParallelForSimdDirective *D);
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00001920 void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective *D);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00001921 void VisitOMPTaskDirective(const OMPTaskDirective *D);
Alexey Bataev68446b72014-07-18 07:47:19 +00001922 void VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D);
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00001923 void VisitOMPBarrierDirective(const OMPBarrierDirective *D);
Alexey Bataev2df347a2014-07-18 10:17:07 +00001924 void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00001925 void VisitOMPTaskgroupDirective(const OMPTaskgroupDirective *D);
Alexey Bataev6d4ed052015-07-01 06:57:41 +00001926 void
1927 VisitOMPCancellationPointDirective(const OMPCancellationPointDirective *D);
Alexey Bataev80909872015-07-02 11:25:17 +00001928 void VisitOMPCancelDirective(const OMPCancelDirective *D);
Alexey Bataev6125da92014-07-21 11:26:11 +00001929 void VisitOMPFlushDirective(const OMPFlushDirective *D);
Alexey Bataev9fb6e642014-07-22 06:45:04 +00001930 void VisitOMPOrderedDirective(const OMPOrderedDirective *D);
Alexey Bataev0162e452014-07-22 10:10:35 +00001931 void VisitOMPAtomicDirective(const OMPAtomicDirective *D);
Alexey Bataev0bd520b2014-09-19 08:19:49 +00001932 void VisitOMPTargetDirective(const OMPTargetDirective *D);
Michael Wong65f367f2015-07-21 13:44:28 +00001933 void VisitOMPTargetDataDirective(const OMPTargetDataDirective *D);
Alexey Bataev13314bf2014-10-09 04:18:56 +00001934 void VisitOMPTeamsDirective(const OMPTeamsDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001935
Guy Benyei11169dd2012-12-18 14:30:41 +00001936private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001937 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001938 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1939 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001940 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1941 void AddStmt(const Stmt *S);
1942 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001943 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001944 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001945 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001946};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00001947} // end anonyous namespace
Guy Benyei11169dd2012-12-18 14:30:41 +00001948
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001949void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001950 // 'S' should always be non-null, since it comes from the
1951 // statement we are visiting.
1952 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1953}
1954
1955void
1956EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1957 if (Qualifier)
1958 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1959}
1960
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001961void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001962 if (S)
1963 WL.push_back(StmtVisit(S, Parent));
1964}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001965void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001966 if (D)
1967 WL.push_back(DeclVisit(D, Parent, isFirst));
1968}
1969void EnqueueVisitor::
1970 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1971 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001972 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001973}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001974void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001975 if (D)
1976 WL.push_back(MemberRefVisit(D, L, Parent));
1977}
1978void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1979 if (TI)
1980 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1981 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001982void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001983 unsigned size = WL.size();
Benjamin Kramer642f1732015-07-02 21:03:14 +00001984 for (const Stmt *SubStmt : S->children()) {
1985 AddStmt(SubStmt);
Guy Benyei11169dd2012-12-18 14:30:41 +00001986 }
1987 if (size == WL.size())
1988 return;
1989 // Now reverse the entries we just added. This will match the DFS
1990 // ordering performed by the worklist.
1991 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1992 std::reverse(I, E);
1993}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001994namespace {
1995class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1996 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001997 /// \brief Process clauses with list of variables.
1998 template <typename T>
1999 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002000public:
2001 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
2002#define OPENMP_CLAUSE(Name, Class) \
2003 void Visit##Class(const Class *C);
2004#include "clang/Basic/OpenMPKinds.def"
2005};
2006
Alexey Bataevaadd52e2014-02-13 05:29:23 +00002007void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
2008 Visitor->AddStmt(C->getCondition());
2009}
2010
Alexey Bataev3778b602014-07-17 07:32:53 +00002011void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
2012 Visitor->AddStmt(C->getCondition());
2013}
2014
Alexey Bataev568a8332014-03-06 06:15:19 +00002015void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
2016 Visitor->AddStmt(C->getNumThreads());
2017}
2018
Alexey Bataev62c87d22014-03-21 04:51:18 +00002019void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
2020 Visitor->AddStmt(C->getSafelen());
2021}
2022
Alexander Musman8bd31e62014-05-27 15:12:19 +00002023void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
2024 Visitor->AddStmt(C->getNumForLoops());
2025}
2026
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002027void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00002028
Alexey Bataevbcbadb62014-05-06 06:04:14 +00002029void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
2030
Alexey Bataev56dafe82014-06-20 07:16:17 +00002031void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
2032 Visitor->AddStmt(C->getChunkSize());
Alexey Bataev040d5402015-05-12 08:35:28 +00002033 Visitor->AddStmt(C->getHelperChunkSize());
Alexey Bataev56dafe82014-06-20 07:16:17 +00002034}
2035
Alexey Bataev142e1fc2014-06-20 09:44:06 +00002036void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *) {}
2037
Alexey Bataev236070f2014-06-20 11:19:47 +00002038void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
2039
Alexey Bataev7aea99a2014-07-17 12:19:31 +00002040void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
2041
Alexey Bataev74ba3a52014-07-17 12:47:03 +00002042void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
2043
Alexey Bataevf98b00c2014-07-23 02:27:21 +00002044void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}
2045
Alexey Bataevdea47612014-07-23 07:46:59 +00002046void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {}
2047
Alexey Bataev67a4f222014-07-23 10:25:33 +00002048void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {}
2049
Alexey Bataev459dec02014-07-24 06:46:57 +00002050void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}
2051
Alexey Bataev82bad8b2014-07-24 08:55:34 +00002052void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
2053
Alexey Bataev756c1962013-09-24 03:17:45 +00002054template<typename T>
2055void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Alexey Bataev03b340a2014-10-21 03:16:40 +00002056 for (const auto *I : Node->varlists()) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00002057 Visitor->AddStmt(I);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002058 }
Alexey Bataev756c1962013-09-24 03:17:45 +00002059}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002060
2061void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002062 VisitOMPClauseList(C);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002063 for (const auto *E : C->private_copies()) {
2064 Visitor->AddStmt(E);
2065 }
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002066}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002067void OMPClauseEnqueue::VisitOMPFirstprivateClause(
2068 const OMPFirstprivateClause *C) {
2069 VisitOMPClauseList(C);
2070}
Alexander Musman1bb328c2014-06-04 13:06:39 +00002071void OMPClauseEnqueue::VisitOMPLastprivateClause(
2072 const OMPLastprivateClause *C) {
2073 VisitOMPClauseList(C);
Alexey Bataev38e89532015-04-16 04:54:05 +00002074 for (auto *E : C->private_copies()) {
2075 Visitor->AddStmt(E);
2076 }
2077 for (auto *E : C->source_exprs()) {
2078 Visitor->AddStmt(E);
2079 }
2080 for (auto *E : C->destination_exprs()) {
2081 Visitor->AddStmt(E);
2082 }
2083 for (auto *E : C->assignment_ops()) {
2084 Visitor->AddStmt(E);
2085 }
Alexander Musman1bb328c2014-06-04 13:06:39 +00002086}
Alexey Bataev758e55e2013-09-06 18:03:48 +00002087void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002088 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00002089}
Alexey Bataevc5e02582014-06-16 07:08:35 +00002090void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
2091 VisitOMPClauseList(C);
Alexey Bataev794ba0d2015-04-10 10:43:45 +00002092 for (auto *E : C->lhs_exprs()) {
2093 Visitor->AddStmt(E);
2094 }
2095 for (auto *E : C->rhs_exprs()) {
2096 Visitor->AddStmt(E);
2097 }
2098 for (auto *E : C->reduction_ops()) {
2099 Visitor->AddStmt(E);
2100 }
Alexey Bataevc5e02582014-06-16 07:08:35 +00002101}
Alexander Musman8dba6642014-04-22 13:09:42 +00002102void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2103 VisitOMPClauseList(C);
Alexander Musman3276a272015-03-21 10:12:56 +00002104 for (const auto *E : C->inits()) {
2105 Visitor->AddStmt(E);
2106 }
2107 for (const auto *E : C->updates()) {
2108 Visitor->AddStmt(E);
2109 }
2110 for (const auto *E : C->finals()) {
2111 Visitor->AddStmt(E);
2112 }
Alexander Musman8dba6642014-04-22 13:09:42 +00002113 Visitor->AddStmt(C->getStep());
Alexander Musman3276a272015-03-21 10:12:56 +00002114 Visitor->AddStmt(C->getCalcStep());
Alexander Musman8dba6642014-04-22 13:09:42 +00002115}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002116void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2117 VisitOMPClauseList(C);
2118 Visitor->AddStmt(C->getAlignment());
2119}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002120void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2121 VisitOMPClauseList(C);
Alexey Bataevf56f98c2015-04-16 05:39:01 +00002122 for (auto *E : C->source_exprs()) {
2123 Visitor->AddStmt(E);
2124 }
2125 for (auto *E : C->destination_exprs()) {
2126 Visitor->AddStmt(E);
2127 }
2128 for (auto *E : C->assignment_ops()) {
2129 Visitor->AddStmt(E);
2130 }
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002131}
Alexey Bataevbae9a792014-06-27 10:37:06 +00002132void
2133OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
2134 VisitOMPClauseList(C);
Alexey Bataeva63048e2015-03-23 06:18:07 +00002135 for (auto *E : C->source_exprs()) {
2136 Visitor->AddStmt(E);
2137 }
2138 for (auto *E : C->destination_exprs()) {
2139 Visitor->AddStmt(E);
2140 }
2141 for (auto *E : C->assignment_ops()) {
2142 Visitor->AddStmt(E);
2143 }
Alexey Bataevbae9a792014-06-27 10:37:06 +00002144}
Alexey Bataev6125da92014-07-21 11:26:11 +00002145void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2146 VisitOMPClauseList(C);
2147}
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +00002148void OMPClauseEnqueue::VisitOMPDependClause(const OMPDependClause *C) {
2149 VisitOMPClauseList(C);
2150}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002151}
Alexey Bataev756c1962013-09-24 03:17:45 +00002152
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002153void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2154 unsigned size = WL.size();
2155 OMPClauseEnqueue Visitor(this);
2156 Visitor.Visit(S);
2157 if (size == WL.size())
2158 return;
2159 // Now reverse the entries we just added. This will match the DFS
2160 // ordering performed by the worklist.
2161 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2162 std::reverse(I, E);
2163}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002164void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002165 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2166}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002167void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002168 AddDecl(B->getBlockDecl());
2169}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002170void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002171 EnqueueChildren(E);
2172 AddTypeLoc(E->getTypeSourceInfo());
2173}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002174void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
2175 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00002176 E = S->body_rend(); I != E; ++I) {
2177 AddStmt(*I);
2178 }
2179}
2180void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002181VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002182 AddStmt(S->getSubStmt());
2183 AddDeclarationNameInfo(S);
2184 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2185 AddNestedNameSpecifierLoc(QualifierLoc);
2186}
2187
2188void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002189VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002190 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2191 AddDeclarationNameInfo(E);
2192 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2193 AddNestedNameSpecifierLoc(QualifierLoc);
2194 if (!E->isImplicitAccess())
2195 AddStmt(E->getBase());
2196}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002197void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002198 // Enqueue the initializer , if any.
2199 AddStmt(E->getInitializer());
2200 // Enqueue the array size, if any.
2201 AddStmt(E->getArraySize());
2202 // Enqueue the allocated type.
2203 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2204 // Enqueue the placement arguments.
2205 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2206 AddStmt(E->getPlacementArg(I-1));
2207}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002208void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002209 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2210 AddStmt(CE->getArg(I-1));
2211 AddStmt(CE->getCallee());
2212 AddStmt(CE->getArg(0));
2213}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002214void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2215 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002216 // Visit the name of the type being destroyed.
2217 AddTypeLoc(E->getDestroyedTypeInfo());
2218 // Visit the scope type that looks disturbingly like the nested-name-specifier
2219 // but isn't.
2220 AddTypeLoc(E->getScopeTypeInfo());
2221 // Visit the nested-name-specifier.
2222 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2223 AddNestedNameSpecifierLoc(QualifierLoc);
2224 // Visit base expression.
2225 AddStmt(E->getBase());
2226}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002227void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2228 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002229 AddTypeLoc(E->getTypeSourceInfo());
2230}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002231void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2232 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002233 EnqueueChildren(E);
2234 AddTypeLoc(E->getTypeSourceInfo());
2235}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002236void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002237 EnqueueChildren(E);
2238 if (E->isTypeOperand())
2239 AddTypeLoc(E->getTypeOperandSourceInfo());
2240}
2241
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002242void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2243 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002244 EnqueueChildren(E);
2245 AddTypeLoc(E->getTypeSourceInfo());
2246}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002247void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002248 EnqueueChildren(E);
2249 if (E->isTypeOperand())
2250 AddTypeLoc(E->getTypeOperandSourceInfo());
2251}
2252
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002253void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002254 EnqueueChildren(S);
2255 AddDecl(S->getExceptionDecl());
2256}
2257
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002258void EnqueueVisitor::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002259 AddStmt(S->getBody());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002260 AddStmt(S->getRangeInit());
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002261 AddDecl(S->getLoopVariable());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002262}
2263
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002264void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002265 if (DR->hasExplicitTemplateArgs()) {
2266 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2267 }
2268 WL.push_back(DeclRefExprParts(DR, Parent));
2269}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002270void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2271 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002272 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2273 AddDeclarationNameInfo(E);
2274 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2275}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002276void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002277 unsigned size = WL.size();
2278 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002279 for (const auto *D : S->decls()) {
2280 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002281 isFirst = false;
2282 }
2283 if (size == WL.size())
2284 return;
2285 // Now reverse the entries we just added. This will match the DFS
2286 // ordering performed by the worklist.
2287 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2288 std::reverse(I, E);
2289}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002290void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002291 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002292 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002293 D = E->designators_rbegin(), DEnd = E->designators_rend();
2294 D != DEnd; ++D) {
2295 if (D->isFieldDesignator()) {
2296 if (FieldDecl *Field = D->getField())
2297 AddMemberRef(Field, D->getFieldLoc());
2298 continue;
2299 }
2300 if (D->isArrayDesignator()) {
2301 AddStmt(E->getArrayIndex(*D));
2302 continue;
2303 }
2304 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2305 AddStmt(E->getArrayRangeEnd(*D));
2306 AddStmt(E->getArrayRangeStart(*D));
2307 }
2308}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002309void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002310 EnqueueChildren(E);
2311 AddTypeLoc(E->getTypeInfoAsWritten());
2312}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002313void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002314 AddStmt(FS->getBody());
2315 AddStmt(FS->getInc());
2316 AddStmt(FS->getCond());
2317 AddDecl(FS->getConditionVariable());
2318 AddStmt(FS->getInit());
2319}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002320void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002321 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2322}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002323void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002324 AddStmt(If->getElse());
2325 AddStmt(If->getThen());
2326 AddStmt(If->getCond());
2327 AddDecl(If->getConditionVariable());
2328}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002329void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002330 // We care about the syntactic form of the initializer list, only.
2331 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2332 IE = Syntactic;
2333 EnqueueChildren(IE);
2334}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002335void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002336 WL.push_back(MemberExprParts(M, Parent));
2337
2338 // If the base of the member access expression is an implicit 'this', don't
2339 // visit it.
2340 // FIXME: If we ever want to show these implicit accesses, this will be
2341 // unfortunate. However, clang_getCursor() relies on this behavior.
Argyrios Kyrtzidis58d0e7a2015-03-13 04:40:07 +00002342 if (M->isImplicitAccess())
2343 return;
2344
2345 // Ignore base anonymous struct/union fields, otherwise they will shadow the
2346 // real field that that we are interested in.
2347 if (auto *SubME = dyn_cast<MemberExpr>(M->getBase())) {
2348 if (auto *FD = dyn_cast_or_null<FieldDecl>(SubME->getMemberDecl())) {
2349 if (FD->isAnonymousStructOrUnion()) {
2350 AddStmt(SubME->getBase());
2351 return;
2352 }
2353 }
2354 }
2355
2356 AddStmt(M->getBase());
Guy Benyei11169dd2012-12-18 14:30:41 +00002357}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002358void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002359 AddTypeLoc(E->getEncodedTypeSourceInfo());
2360}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002361void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002362 EnqueueChildren(M);
2363 AddTypeLoc(M->getClassReceiverTypeInfo());
2364}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002365void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002366 // Visit the components of the offsetof expression.
2367 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2368 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2369 const OffsetOfNode &Node = E->getComponent(I-1);
2370 switch (Node.getKind()) {
2371 case OffsetOfNode::Array:
2372 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2373 break;
2374 case OffsetOfNode::Field:
2375 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2376 break;
2377 case OffsetOfNode::Identifier:
2378 case OffsetOfNode::Base:
2379 continue;
2380 }
2381 }
2382 // Visit the type into which we're computing the offset.
2383 AddTypeLoc(E->getTypeSourceInfo());
2384}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002385void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002386 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2387 WL.push_back(OverloadExprParts(E, Parent));
2388}
2389void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002390 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002391 EnqueueChildren(E);
2392 if (E->isArgumentType())
2393 AddTypeLoc(E->getArgumentTypeInfo());
2394}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002395void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002396 EnqueueChildren(S);
2397}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002398void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002399 AddStmt(S->getBody());
2400 AddStmt(S->getCond());
2401 AddDecl(S->getConditionVariable());
2402}
2403
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002404void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002405 AddStmt(W->getBody());
2406 AddStmt(W->getCond());
2407 AddDecl(W->getConditionVariable());
2408}
2409
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002410void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002411 for (unsigned I = E->getNumArgs(); I > 0; --I)
2412 AddTypeLoc(E->getArg(I-1));
2413}
2414
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002415void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002416 AddTypeLoc(E->getQueriedTypeSourceInfo());
2417}
2418
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002419void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002420 EnqueueChildren(E);
2421}
2422
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002423void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002424 VisitOverloadExpr(U);
2425 if (!U->isImplicitAccess())
2426 AddStmt(U->getBase());
2427}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002428void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002429 AddStmt(E->getSubExpr());
2430 AddTypeLoc(E->getWrittenTypeInfo());
2431}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002432void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002433 WL.push_back(SizeOfPackExprParts(E, Parent));
2434}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002435void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002436 // If the opaque value has a source expression, just transparently
2437 // visit that. This is useful for (e.g.) pseudo-object expressions.
2438 if (Expr *SourceExpr = E->getSourceExpr())
2439 return Visit(SourceExpr);
2440}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002441void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002442 AddStmt(E->getBody());
2443 WL.push_back(LambdaExprParts(E, Parent));
2444}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002445void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002446 // Treat the expression like its syntactic form.
2447 Visit(E->getSyntacticForm());
2448}
2449
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002450void EnqueueVisitor::VisitOMPExecutableDirective(
2451 const OMPExecutableDirective *D) {
2452 EnqueueChildren(D);
2453 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2454 E = D->clauses().end();
2455 I != E; ++I)
2456 EnqueueChildren(*I);
2457}
2458
Alexander Musman3aaab662014-08-19 11:27:13 +00002459void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
2460 VisitOMPExecutableDirective(D);
2461}
2462
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002463void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2464 VisitOMPExecutableDirective(D);
2465}
2466
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002467void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002468 VisitOMPLoopDirective(D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002469}
2470
Alexey Bataevf29276e2014-06-18 04:14:57 +00002471void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002472 VisitOMPLoopDirective(D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002473}
2474
Alexander Musmanf82886e2014-09-18 05:12:34 +00002475void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
2476 VisitOMPLoopDirective(D);
2477}
2478
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002479void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2480 VisitOMPExecutableDirective(D);
2481}
2482
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002483void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2484 VisitOMPExecutableDirective(D);
2485}
2486
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002487void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2488 VisitOMPExecutableDirective(D);
2489}
2490
Alexander Musman80c22892014-07-17 08:54:58 +00002491void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2492 VisitOMPExecutableDirective(D);
2493}
2494
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002495void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2496 VisitOMPExecutableDirective(D);
2497 AddDeclarationNameInfo(D);
2498}
2499
Alexey Bataev4acb8592014-07-07 13:01:15 +00002500void
2501EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002502 VisitOMPLoopDirective(D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002503}
2504
Alexander Musmane4e893b2014-09-23 09:33:00 +00002505void EnqueueVisitor::VisitOMPParallelForSimdDirective(
2506 const OMPParallelForSimdDirective *D) {
2507 VisitOMPLoopDirective(D);
2508}
2509
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002510void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2511 const OMPParallelSectionsDirective *D) {
2512 VisitOMPExecutableDirective(D);
2513}
2514
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002515void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2516 VisitOMPExecutableDirective(D);
2517}
2518
Alexey Bataev68446b72014-07-18 07:47:19 +00002519void
2520EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2521 VisitOMPExecutableDirective(D);
2522}
2523
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002524void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2525 VisitOMPExecutableDirective(D);
2526}
2527
Alexey Bataev2df347a2014-07-18 10:17:07 +00002528void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2529 VisitOMPExecutableDirective(D);
2530}
2531
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002532void EnqueueVisitor::VisitOMPTaskgroupDirective(
2533 const OMPTaskgroupDirective *D) {
2534 VisitOMPExecutableDirective(D);
2535}
2536
Alexey Bataev6125da92014-07-21 11:26:11 +00002537void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2538 VisitOMPExecutableDirective(D);
2539}
2540
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002541void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2542 VisitOMPExecutableDirective(D);
2543}
2544
Alexey Bataev0162e452014-07-22 10:10:35 +00002545void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2546 VisitOMPExecutableDirective(D);
2547}
2548
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002549void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
2550 VisitOMPExecutableDirective(D);
2551}
2552
Michael Wong65f367f2015-07-21 13:44:28 +00002553void EnqueueVisitor::VisitOMPTargetDataDirective(const
2554 OMPTargetDataDirective *D) {
2555 VisitOMPExecutableDirective(D);
2556}
2557
Alexey Bataev13314bf2014-10-09 04:18:56 +00002558void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {
2559 VisitOMPExecutableDirective(D);
2560}
2561
Alexey Bataev6d4ed052015-07-01 06:57:41 +00002562void EnqueueVisitor::VisitOMPCancellationPointDirective(
2563 const OMPCancellationPointDirective *D) {
2564 VisitOMPExecutableDirective(D);
2565}
2566
Alexey Bataev80909872015-07-02 11:25:17 +00002567void EnqueueVisitor::VisitOMPCancelDirective(const OMPCancelDirective *D) {
2568 VisitOMPExecutableDirective(D);
2569}
2570
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002571void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002572 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2573}
2574
2575bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2576 if (RegionOfInterest.isValid()) {
2577 SourceRange Range = getRawCursorExtent(C);
2578 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2579 return false;
2580 }
2581 return true;
2582}
2583
2584bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2585 while (!WL.empty()) {
2586 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002587 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002588
2589 // Set the Parent field, then back to its old value once we're done.
2590 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2591
2592 switch (LI.getKind()) {
2593 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002594 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002595 if (!D)
2596 continue;
2597
2598 // For now, perform default visitation for Decls.
2599 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2600 cast<DeclVisit>(&LI)->isFirst())))
2601 return true;
2602
2603 continue;
2604 }
2605 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2606 const ASTTemplateArgumentListInfo *ArgList =
2607 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2608 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2609 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2610 Arg != ArgEnd; ++Arg) {
2611 if (VisitTemplateArgumentLoc(*Arg))
2612 return true;
2613 }
2614 continue;
2615 }
2616 case VisitorJob::TypeLocVisitKind: {
2617 // Perform default visitation for TypeLocs.
2618 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2619 return true;
2620 continue;
2621 }
2622 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002623 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002624 if (LabelStmt *stmt = LS->getStmt()) {
2625 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2626 TU))) {
2627 return true;
2628 }
2629 }
2630 continue;
2631 }
2632
2633 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2634 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2635 if (VisitNestedNameSpecifierLoc(V->get()))
2636 return true;
2637 continue;
2638 }
2639
2640 case VisitorJob::DeclarationNameInfoVisitKind: {
2641 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2642 ->get()))
2643 return true;
2644 continue;
2645 }
2646 case VisitorJob::MemberRefVisitKind: {
2647 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2648 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2649 return true;
2650 continue;
2651 }
2652 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002653 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002654 if (!S)
2655 continue;
2656
2657 // Update the current cursor.
2658 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2659 if (!IsInRegionOfInterest(Cursor))
2660 continue;
2661 switch (Visitor(Cursor, Parent, ClientData)) {
2662 case CXChildVisit_Break: return true;
2663 case CXChildVisit_Continue: break;
2664 case CXChildVisit_Recurse:
2665 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002666 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002667 EnqueueWorkList(WL, S);
2668 break;
2669 }
2670 continue;
2671 }
2672 case VisitorJob::MemberExprPartsKind: {
2673 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002674 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002675
2676 // Visit the nested-name-specifier
2677 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2678 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2679 return true;
2680
2681 // Visit the declaration name.
2682 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2683 return true;
2684
2685 // Visit the explicitly-specified template arguments, if any.
2686 if (M->hasExplicitTemplateArgs()) {
2687 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2688 *ArgEnd = Arg + M->getNumTemplateArgs();
2689 Arg != ArgEnd; ++Arg) {
2690 if (VisitTemplateArgumentLoc(*Arg))
2691 return true;
2692 }
2693 }
2694 continue;
2695 }
2696 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002697 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002698 // Visit nested-name-specifier, if present.
2699 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2700 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2701 return true;
2702 // Visit declaration name.
2703 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2704 return true;
2705 continue;
2706 }
2707 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002708 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002709 // Visit the nested-name-specifier.
2710 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2711 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2712 return true;
2713 // Visit the declaration name.
2714 if (VisitDeclarationNameInfo(O->getNameInfo()))
2715 return true;
2716 // Visit the overloaded declaration reference.
2717 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2718 return true;
2719 continue;
2720 }
2721 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002722 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002723 NamedDecl *Pack = E->getPack();
2724 if (isa<TemplateTypeParmDecl>(Pack)) {
2725 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2726 E->getPackLoc(), TU)))
2727 return true;
2728
2729 continue;
2730 }
2731
2732 if (isa<TemplateTemplateParmDecl>(Pack)) {
2733 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2734 E->getPackLoc(), TU)))
2735 return true;
2736
2737 continue;
2738 }
2739
2740 // Non-type template parameter packs and function parameter packs are
2741 // treated like DeclRefExpr cursors.
2742 continue;
2743 }
2744
2745 case VisitorJob::LambdaExprPartsKind: {
2746 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002747 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002748 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2749 CEnd = E->explicit_capture_end();
2750 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002751 // FIXME: Lambda init-captures.
2752 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002753 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002754
Guy Benyei11169dd2012-12-18 14:30:41 +00002755 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2756 C->getLocation(),
2757 TU)))
2758 return true;
2759 }
2760
2761 // Visit parameters and return type, if present.
2762 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2763 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2764 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2765 // Visit the whole type.
2766 if (Visit(TL))
2767 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002768 } else if (FunctionProtoTypeLoc Proto =
2769 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002770 if (E->hasExplicitParameters()) {
2771 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002772 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2773 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002774 return true;
2775 } else {
2776 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002777 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002778 return true;
2779 }
2780 }
2781 }
2782 break;
2783 }
2784
2785 case VisitorJob::PostChildrenVisitKind:
2786 if (PostChildrenVisitor(Parent, ClientData))
2787 return true;
2788 break;
2789 }
2790 }
2791 return false;
2792}
2793
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002794bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002795 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002796 if (!WorkListFreeList.empty()) {
2797 WL = WorkListFreeList.back();
2798 WL->clear();
2799 WorkListFreeList.pop_back();
2800 }
2801 else {
2802 WL = new VisitorWorkList();
2803 WorkListCache.push_back(WL);
2804 }
2805 EnqueueWorkList(*WL, S);
2806 bool result = RunVisitorWorkList(*WL);
2807 WorkListFreeList.push_back(WL);
2808 return result;
2809}
2810
2811namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002812typedef SmallVector<SourceRange, 4> RefNamePieces;
Craig Topper69186e72014-06-08 08:38:04 +00002813RefNamePieces
2814buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2815 const DeclarationNameInfo &NI, const SourceRange &QLoc,
2816 const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002817 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2818 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2819 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2820
2821 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2822
2823 RefNamePieces Pieces;
2824
2825 if (WantQualifier && QLoc.isValid())
2826 Pieces.push_back(QLoc);
2827
2828 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2829 Pieces.push_back(NI.getLoc());
2830
2831 if (WantTemplateArgs && TemplateArgs)
2832 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2833 TemplateArgs->RAngleLoc));
2834
2835 if (Kind == DeclarationName::CXXOperatorName) {
2836 Pieces.push_back(SourceLocation::getFromRawEncoding(
2837 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2838 Pieces.push_back(SourceLocation::getFromRawEncoding(
2839 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2840 }
2841
2842 if (WantSinglePiece) {
2843 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2844 Pieces.clear();
2845 Pieces.push_back(R);
2846 }
2847
2848 return Pieces;
2849}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002850}
Guy Benyei11169dd2012-12-18 14:30:41 +00002851
2852//===----------------------------------------------------------------------===//
2853// Misc. API hooks.
2854//===----------------------------------------------------------------------===//
2855
Chad Rosier05c71aa2013-03-27 18:28:23 +00002856static void fatal_error_handler(void *user_data, const std::string& reason,
2857 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002858 // Write the result out to stderr avoiding errs() because raw_ostreams can
2859 // call report_fatal_error.
2860 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2861 ::abort();
2862}
2863
Chandler Carruth66660742014-06-27 16:37:27 +00002864namespace {
2865struct RegisterFatalErrorHandler {
2866 RegisterFatalErrorHandler() {
2867 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2868 }
2869};
2870}
2871
2872static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
2873
Guy Benyei11169dd2012-12-18 14:30:41 +00002874extern "C" {
2875CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2876 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002877 // We use crash recovery to make some of our APIs more reliable, implicitly
2878 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002879 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2880 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002881
Chandler Carruth66660742014-06-27 16:37:27 +00002882 // Look through the managed static to trigger construction of the managed
2883 // static which registers our fatal error handler. This ensures it is only
2884 // registered once.
2885 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00002886
Adrian Prantlbc068582015-07-08 01:00:30 +00002887 // Initialize targets for clang module support.
2888 llvm::InitializeAllTargets();
2889 llvm::InitializeAllTargetMCs();
2890 llvm::InitializeAllAsmPrinters();
2891 llvm::InitializeAllAsmParsers();
2892
Adrian Prantlfb2398d2015-07-17 01:19:54 +00002893 CIndexer *CIdxr = new CIndexer();
2894
Guy Benyei11169dd2012-12-18 14:30:41 +00002895 if (excludeDeclarationsFromPCH)
2896 CIdxr->setOnlyLocalDecls();
2897 if (displayDiagnostics)
2898 CIdxr->setDisplayDiagnostics();
2899
2900 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2901 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2902 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2903 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2904 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2905 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2906
2907 return CIdxr;
2908}
2909
2910void clang_disposeIndex(CXIndex CIdx) {
2911 if (CIdx)
2912 delete static_cast<CIndexer *>(CIdx);
2913}
2914
2915void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2916 if (CIdx)
2917 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2918}
2919
2920unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2921 if (CIdx)
2922 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2923 return 0;
2924}
2925
2926void clang_toggleCrashRecovery(unsigned isEnabled) {
2927 if (isEnabled)
2928 llvm::CrashRecoveryContext::Enable();
2929 else
2930 llvm::CrashRecoveryContext::Disable();
2931}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002932
Guy Benyei11169dd2012-12-18 14:30:41 +00002933CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2934 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002935 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002936 enum CXErrorCode Result =
2937 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002938 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002939 assert((TU && Result == CXError_Success) ||
2940 (!TU && Result != CXError_Success));
2941 return TU;
2942}
2943
2944enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2945 const char *ast_filename,
2946 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002947 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002948 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002949
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002950 if (!CIdx || !ast_filename || !out_TU)
2951 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002952
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002953 LOG_FUNC_SECTION {
2954 *Log << ast_filename;
2955 }
2956
Guy Benyei11169dd2012-12-18 14:30:41 +00002957 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2958 FileSystemOptions FileSystemOpts;
2959
Justin Bognerd512c1e2014-10-15 00:33:06 +00002960 IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
2961 CompilerInstance::createDiagnostics(new DiagnosticOptions());
David Blaikie6f7382d2014-08-10 19:08:04 +00002962 std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
Adrian Prantlfb2398d2015-07-17 01:19:54 +00002963 ast_filename, CXXIdx->getPCHContainerOperations()->getRawReader(), Diags,
2964 FileSystemOpts, CXXIdx->getOnlyLocalDecls(), None,
David Blaikie6f7382d2014-08-10 19:08:04 +00002965 /*CaptureDiagnostics=*/true,
2966 /*AllowPCHWithCompilerErrors=*/true,
2967 /*UserFilesAreVolatile=*/true);
2968 *out_TU = MakeCXTranslationUnit(CXXIdx, AU.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002969 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002970}
2971
2972unsigned clang_defaultEditingTranslationUnitOptions() {
2973 return CXTranslationUnit_PrecompiledPreamble |
2974 CXTranslationUnit_CacheCompletionResults;
2975}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002976
Guy Benyei11169dd2012-12-18 14:30:41 +00002977CXTranslationUnit
2978clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2979 const char *source_filename,
2980 int num_command_line_args,
2981 const char * const *command_line_args,
2982 unsigned num_unsaved_files,
2983 struct CXUnsavedFile *unsaved_files) {
2984 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2985 return clang_parseTranslationUnit(CIdx, source_filename,
2986 command_line_args, num_command_line_args,
2987 unsaved_files, num_unsaved_files,
2988 Options);
2989}
2990
2991struct ParseTranslationUnitInfo {
2992 CXIndex CIdx;
2993 const char *source_filename;
2994 const char *const *command_line_args;
2995 int num_command_line_args;
Alp Toker9d85b182014-07-07 01:23:14 +00002996 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00002997 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002998 CXTranslationUnit *out_TU;
Alp Toker5c532982014-07-07 22:42:03 +00002999 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003000};
3001static void clang_parseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00003002 const ParseTranslationUnitInfo *PTUI =
3003 static_cast<ParseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00003004 CXIndex CIdx = PTUI->CIdx;
3005 const char *source_filename = PTUI->source_filename;
3006 const char * const *command_line_args = PTUI->command_line_args;
3007 int num_command_line_args = PTUI->num_command_line_args;
Guy Benyei11169dd2012-12-18 14:30:41 +00003008 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003009 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00003010
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003011 // Set up the initial return values.
3012 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00003013 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003014
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003015 // Check arguments.
Alp Toker9d85b182014-07-07 01:23:14 +00003016 if (!CIdx || !out_TU) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003017 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00003018 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003019 }
3020
Guy Benyei11169dd2012-12-18 14:30:41 +00003021 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3022
3023 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3024 setThreadBackgroundPriority();
3025
3026 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
3027 // FIXME: Add a flag for modules.
3028 TranslationUnitKind TUKind
3029 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00003030 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00003031 = options & CXTranslationUnit_CacheCompletionResults;
3032 bool IncludeBriefCommentsInCodeCompletion
3033 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
3034 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
3035 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
3036
3037 // Configure the diagnostics.
3038 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00003039 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00003040
3041 // Recover resources if we crash before exiting this function.
3042 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
3043 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00003044 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00003045
Ahmed Charlesb8984322014-03-07 20:03:18 +00003046 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3047 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003048
3049 // Recover resources if we crash before exiting this function.
3050 llvm::CrashRecoveryContextCleanupRegistrar<
3051 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3052
Alp Toker9d85b182014-07-07 01:23:14 +00003053 for (auto &UF : PTUI->unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003054 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003055 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003056 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003057 }
3058
Ahmed Charlesb8984322014-03-07 20:03:18 +00003059 std::unique_ptr<std::vector<const char *>> Args(
3060 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003061
3062 // Recover resources if we crash before exiting this method.
3063 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
3064 ArgsCleanup(Args.get());
3065
3066 // Since the Clang C library is primarily used by batch tools dealing with
3067 // (often very broken) source code, where spell-checking can have a
3068 // significant negative impact on performance (particularly when
3069 // precompiled headers are involved), we disable it by default.
3070 // Only do this if we haven't found a spell-checking-related argument.
3071 bool FoundSpellCheckingArgument = false;
3072 for (int I = 0; I != num_command_line_args; ++I) {
3073 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
3074 strcmp(command_line_args[I], "-fspell-checking") == 0) {
3075 FoundSpellCheckingArgument = true;
3076 break;
3077 }
3078 }
3079 if (!FoundSpellCheckingArgument)
3080 Args->push_back("-fno-spell-checking");
3081
3082 Args->insert(Args->end(), command_line_args,
3083 command_line_args + num_command_line_args);
3084
3085 // The 'source_filename' argument is optional. If the caller does not
3086 // specify it then it is assumed that the source file is specified
3087 // in the actual argument list.
3088 // Put the source file after command_line_args otherwise if '-x' flag is
3089 // present it will be unused.
3090 if (source_filename)
3091 Args->push_back(source_filename);
3092
3093 // Do we need the detailed preprocessing record?
3094 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
3095 Args->push_back("-Xclang");
3096 Args->push_back("-detailed-preprocessing-record");
3097 }
3098
3099 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00003100 std::unique_ptr<ASTUnit> ErrUnit;
3101 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003102 Args->data(), Args->data() + Args->size(),
3103 CXXIdx->getPCHContainerOperations(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00003104 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
3105 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
3106 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
3107 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
3108 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
3109 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00003110
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003111 // Early failures in LoadFromCommandLine may return with ErrUnit unset.
3112 if (!Unit && !ErrUnit) {
3113 PTUI->result = CXError_ASTReadError;
3114 return;
3115 }
3116
Guy Benyei11169dd2012-12-18 14:30:41 +00003117 if (NumErrors != Diags->getClient()->getNumErrors()) {
3118 // Make sure to check that 'Unit' is non-NULL.
3119 if (CXXIdx->getDisplayDiagnostics())
3120 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
3121 }
3122
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003123 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
3124 PTUI->result = CXError_ASTReadError;
3125 } else {
Ahmed Charles9a16beb2014-03-07 19:33:25 +00003126 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003127 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
3128 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003129}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003130
3131CXTranslationUnit
3132clang_parseTranslationUnit(CXIndex CIdx,
3133 const char *source_filename,
3134 const char *const *command_line_args,
3135 int num_command_line_args,
3136 struct CXUnsavedFile *unsaved_files,
3137 unsigned num_unsaved_files,
3138 unsigned options) {
3139 CXTranslationUnit TU;
3140 enum CXErrorCode Result = clang_parseTranslationUnit2(
3141 CIdx, source_filename, command_line_args, num_command_line_args,
3142 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00003143 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003144 assert((TU && Result == CXError_Success) ||
3145 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003146 return TU;
3147}
3148
3149enum CXErrorCode clang_parseTranslationUnit2(
3150 CXIndex CIdx,
3151 const char *source_filename,
3152 const char *const *command_line_args,
3153 int num_command_line_args,
3154 struct CXUnsavedFile *unsaved_files,
3155 unsigned num_unsaved_files,
3156 unsigned options,
3157 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003158 LOG_FUNC_SECTION {
3159 *Log << source_filename << ": ";
3160 for (int i = 0; i != num_command_line_args; ++i)
3161 *Log << command_line_args[i] << " ";
3162 }
3163
Alp Toker9d85b182014-07-07 01:23:14 +00003164 if (num_unsaved_files && !unsaved_files)
3165 return CXError_InvalidArguments;
3166
Alp Toker5c532982014-07-07 22:42:03 +00003167 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00003168 ParseTranslationUnitInfo PTUI = {
3169 CIdx,
3170 source_filename,
3171 command_line_args,
3172 num_command_line_args,
3173 llvm::makeArrayRef(unsaved_files, num_unsaved_files),
3174 options,
3175 out_TU,
Alp Toker5c532982014-07-07 22:42:03 +00003176 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00003177 llvm::CrashRecoveryContext CRC;
3178
3179 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
3180 fprintf(stderr, "libclang: crash detected during parsing: {\n");
3181 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3182 fprintf(stderr, " 'command_line_args' : [");
3183 for (int i = 0; i != num_command_line_args; ++i) {
3184 if (i)
3185 fprintf(stderr, ", ");
3186 fprintf(stderr, "'%s'", command_line_args[i]);
3187 }
3188 fprintf(stderr, "],\n");
3189 fprintf(stderr, " 'unsaved_files' : [");
3190 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3191 if (i)
3192 fprintf(stderr, ", ");
3193 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3194 unsaved_files[i].Length);
3195 }
3196 fprintf(stderr, "],\n");
3197 fprintf(stderr, " 'options' : %d,\n", options);
3198 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003199
3200 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003201 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003202 if (CXTranslationUnit *TU = PTUI.out_TU)
3203 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003204 }
Alp Toker5c532982014-07-07 22:42:03 +00003205
3206 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003207}
3208
3209unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
3210 return CXSaveTranslationUnit_None;
3211}
3212
3213namespace {
3214
3215struct SaveTranslationUnitInfo {
3216 CXTranslationUnit TU;
3217 const char *FileName;
3218 unsigned options;
3219 CXSaveError result;
3220};
3221
3222}
3223
3224static void clang_saveTranslationUnit_Impl(void *UserData) {
3225 SaveTranslationUnitInfo *STUI =
3226 static_cast<SaveTranslationUnitInfo*>(UserData);
3227
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003228 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003229 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3230 setThreadBackgroundPriority();
3231
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003232 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00003233 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
3234}
3235
3236int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3237 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003238 LOG_FUNC_SECTION {
3239 *Log << TU << ' ' << FileName;
3240 }
3241
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003242 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003243 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003244 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003245 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003246
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003247 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003248 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3249 if (!CXXUnit->hasSema())
3250 return CXSaveError_InvalidTU;
3251
3252 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
3253
3254 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3255 getenv("LIBCLANG_NOTHREADS")) {
3256 clang_saveTranslationUnit_Impl(&STUI);
3257
3258 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3259 PrintLibclangResourceUsage(TU);
3260
3261 return STUI.result;
3262 }
3263
3264 // We have an AST that has invalid nodes due to compiler errors.
3265 // Use a crash recovery thread for protection.
3266
3267 llvm::CrashRecoveryContext CRC;
3268
3269 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
3270 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3271 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3272 fprintf(stderr, " 'options' : %d,\n", options);
3273 fprintf(stderr, "}\n");
3274
3275 return CXSaveError_Unknown;
3276
3277 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3278 PrintLibclangResourceUsage(TU);
3279 }
3280
3281 return STUI.result;
3282}
3283
3284void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3285 if (CTUnit) {
3286 // If the translation unit has been marked as unsafe to free, just discard
3287 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003288 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3289 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003290 return;
3291
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003292 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003293 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003294 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3295 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003296 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003297 delete CTUnit;
3298 }
3299}
3300
3301unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3302 return CXReparse_None;
3303}
3304
3305struct ReparseTranslationUnitInfo {
3306 CXTranslationUnit TU;
Alp Toker9d85b182014-07-07 01:23:14 +00003307 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00003308 unsigned options;
Alp Toker5c532982014-07-07 22:42:03 +00003309 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003310};
3311
3312static void clang_reparseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00003313 const ReparseTranslationUnitInfo *RTUI =
3314 static_cast<ReparseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00003315 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003316 unsigned options = RTUI->options;
3317 (void) options;
3318
3319 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003320 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003321 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003322 RTUI->result = CXError_InvalidArguments;
3323 return;
3324 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003325
3326 // Reset the associated diagnostics.
3327 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003328 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003329
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003330 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003331 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3332 setThreadBackgroundPriority();
3333
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003334 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003335 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003336
3337 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3338 new std::vector<ASTUnit::RemappedFile>());
3339
Guy Benyei11169dd2012-12-18 14:30:41 +00003340 // Recover resources if we crash before exiting this function.
3341 llvm::CrashRecoveryContextCleanupRegistrar<
3342 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003343
3344 for (auto &UF : RTUI->unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003345 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003346 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003347 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003348 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003349
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003350 if (!CXXUnit->Reparse(CXXIdx->getPCHContainerOperations(),
3351 *RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003352 RTUI->result = CXError_Success;
3353 else if (isASTReadError(CXXUnit))
3354 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003355}
3356
3357int clang_reparseTranslationUnit(CXTranslationUnit TU,
3358 unsigned num_unsaved_files,
3359 struct CXUnsavedFile *unsaved_files,
3360 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003361 LOG_FUNC_SECTION {
3362 *Log << TU;
3363 }
3364
Alp Toker9d85b182014-07-07 01:23:14 +00003365 if (num_unsaved_files && !unsaved_files)
3366 return CXError_InvalidArguments;
3367
Alp Toker5c532982014-07-07 22:42:03 +00003368 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00003369 ReparseTranslationUnitInfo RTUI = {
3370 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options,
Alp Toker5c532982014-07-07 22:42:03 +00003371 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00003372
3373 if (getenv("LIBCLANG_NOTHREADS")) {
3374 clang_reparseTranslationUnit_Impl(&RTUI);
Alp Toker5c532982014-07-07 22:42:03 +00003375 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003376 }
3377
3378 llvm::CrashRecoveryContext CRC;
3379
3380 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3381 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003382 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003383 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003384 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3385 PrintLibclangResourceUsage(TU);
3386
Alp Toker5c532982014-07-07 22:42:03 +00003387 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003388}
3389
3390
3391CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003392 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003393 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003394 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003395 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003396
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003397 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003398 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003399}
3400
3401CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003402 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003403 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003404 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003405 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003406
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003407 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003408 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3409}
3410
3411} // end: extern "C"
3412
3413//===----------------------------------------------------------------------===//
3414// CXFile Operations.
3415//===----------------------------------------------------------------------===//
3416
3417extern "C" {
3418CXString clang_getFileName(CXFile SFile) {
3419 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003420 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003421
3422 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003423 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003424}
3425
3426time_t clang_getFileTime(CXFile SFile) {
3427 if (!SFile)
3428 return 0;
3429
3430 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3431 return FEnt->getModificationTime();
3432}
3433
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003434CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003435 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003436 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003437 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003438 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003439
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003440 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003441
3442 FileManager &FMgr = CXXUnit->getFileManager();
3443 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3444}
3445
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003446unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3447 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003448 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003449 LOG_BAD_TU(TU);
3450 return 0;
3451 }
3452
3453 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003454 return 0;
3455
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003456 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003457 FileEntry *FEnt = static_cast<FileEntry *>(file);
3458 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3459 .isFileMultipleIncludeGuarded(FEnt);
3460}
3461
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003462int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3463 if (!file || !outID)
3464 return 1;
3465
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003466 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003467 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3468 outID->data[0] = ID.getDevice();
3469 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003470 outID->data[2] = FEnt->getModificationTime();
3471 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003472}
3473
Argyrios Kyrtzidisac3997e2014-08-16 00:26:19 +00003474int clang_File_isEqual(CXFile file1, CXFile file2) {
3475 if (file1 == file2)
3476 return true;
3477
3478 if (!file1 || !file2)
3479 return false;
3480
3481 FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
3482 FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
3483 return FEnt1->getUniqueID() == FEnt2->getUniqueID();
3484}
3485
Guy Benyei11169dd2012-12-18 14:30:41 +00003486} // end: extern "C"
3487
3488//===----------------------------------------------------------------------===//
3489// CXCursor Operations.
3490//===----------------------------------------------------------------------===//
3491
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003492static const Decl *getDeclFromExpr(const Stmt *E) {
3493 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003494 return getDeclFromExpr(CE->getSubExpr());
3495
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003496 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003497 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003498 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003499 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003500 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003501 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003502 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003503 if (PRE->isExplicitProperty())
3504 return PRE->getExplicitProperty();
3505 // It could be messaging both getter and setter as in:
3506 // ++myobj.myprop;
3507 // in which case prefer to associate the setter since it is less obvious
3508 // from inspecting the source that the setter is going to get called.
3509 if (PRE->isMessagingSetter())
3510 return PRE->getImplicitPropertySetter();
3511 return PRE->getImplicitPropertyGetter();
3512 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003513 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003514 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003515 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003516 if (Expr *Src = OVE->getSourceExpr())
3517 return getDeclFromExpr(Src);
3518
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003519 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003520 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003521 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003522 if (!CE->isElidable())
3523 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003524 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003525 return OME->getMethodDecl();
3526
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003527 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003528 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003529 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003530 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3531 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003532 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003533 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3534 isa<ParmVarDecl>(SizeOfPack->getPack()))
3535 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003536
3537 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003538}
3539
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003540static SourceLocation getLocationFromExpr(const Expr *E) {
3541 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003542 return getLocationFromExpr(CE->getSubExpr());
3543
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003544 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003545 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003546 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003547 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003548 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003549 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003550 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003551 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003552 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003553 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003554 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003555 return PropRef->getLocation();
3556
3557 return E->getLocStart();
3558}
3559
3560extern "C" {
3561
3562unsigned clang_visitChildren(CXCursor parent,
3563 CXCursorVisitor visitor,
3564 CXClientData client_data) {
3565 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3566 /*VisitPreprocessorLast=*/false);
3567 return CursorVis.VisitChildren(parent);
3568}
3569
3570#ifndef __has_feature
3571#define __has_feature(x) 0
3572#endif
3573#if __has_feature(blocks)
3574typedef enum CXChildVisitResult
3575 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3576
3577static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3578 CXClientData client_data) {
3579 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3580 return block(cursor, parent);
3581}
3582#else
3583// If we are compiled with a compiler that doesn't have native blocks support,
3584// define and call the block manually, so the
3585typedef struct _CXChildVisitResult
3586{
3587 void *isa;
3588 int flags;
3589 int reserved;
3590 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3591 CXCursor);
3592} *CXCursorVisitorBlock;
3593
3594static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3595 CXClientData client_data) {
3596 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3597 return block->invoke(block, cursor, parent);
3598}
3599#endif
3600
3601
3602unsigned clang_visitChildrenWithBlock(CXCursor parent,
3603 CXCursorVisitorBlock block) {
3604 return clang_visitChildren(parent, visitWithBlock, block);
3605}
3606
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003607static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003608 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003609 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003610
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003611 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003612 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003613 if (const ObjCPropertyImplDecl *PropImpl =
3614 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003615 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003616 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003617
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003618 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003619 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003620 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003621
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003622 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003623 }
3624
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003625 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003626 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003627
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003628 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003629 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3630 // and returns different names. NamedDecl returns the class name and
3631 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003632 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003633
3634 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003635 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003636
3637 SmallString<1024> S;
3638 llvm::raw_svector_ostream os(S);
3639 ND->printName(os);
3640
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003641 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003642}
3643
3644CXString clang_getCursorSpelling(CXCursor C) {
3645 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003646 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003647
3648 if (clang_isReference(C.kind)) {
3649 switch (C.kind) {
3650 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003651 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003652 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003653 }
3654 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003655 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003656 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003657 }
3658 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003659 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003660 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003661 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003662 }
3663 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003664 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003665 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003666 }
3667 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003668 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003669 assert(Type && "Missing type decl");
3670
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003671 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003672 getAsString());
3673 }
3674 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003675 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003676 assert(Template && "Missing template decl");
3677
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003678 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003679 }
3680
3681 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003682 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003683 assert(NS && "Missing namespace decl");
3684
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003685 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003686 }
3687
3688 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003689 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003690 assert(Field && "Missing member decl");
3691
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003692 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003693 }
3694
3695 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003696 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003697 assert(Label && "Missing label");
3698
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003699 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003700 }
3701
3702 case CXCursor_OverloadedDeclRef: {
3703 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003704 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3705 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003706 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003707 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003708 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003709 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003710 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003711 OverloadedTemplateStorage *Ovl
3712 = Storage.get<OverloadedTemplateStorage*>();
3713 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003714 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003715 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003716 }
3717
3718 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003719 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003720 assert(Var && "Missing variable decl");
3721
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003722 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003723 }
3724
3725 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003726 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003727 }
3728 }
3729
3730 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003731 const Expr *E = getCursorExpr(C);
3732
3733 if (C.kind == CXCursor_ObjCStringLiteral ||
3734 C.kind == CXCursor_StringLiteral) {
3735 const StringLiteral *SLit;
3736 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3737 SLit = OSL->getString();
3738 } else {
3739 SLit = cast<StringLiteral>(E);
3740 }
3741 SmallString<256> Buf;
3742 llvm::raw_svector_ostream OS(Buf);
3743 SLit->outputString(OS);
3744 return cxstring::createDup(OS.str());
3745 }
3746
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003747 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003748 if (D)
3749 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003750 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003751 }
3752
3753 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003754 const Stmt *S = getCursorStmt(C);
3755 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003756 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003757
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003758 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003759 }
3760
3761 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003762 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003763 ->getNameStart());
3764
3765 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003766 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003767 ->getNameStart());
3768
3769 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003770 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003771
3772 if (clang_isDeclaration(C.kind))
3773 return getDeclSpelling(getCursorDecl(C));
3774
3775 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003776 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003777 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003778 }
3779
3780 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003781 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003782 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003783 }
3784
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003785 if (C.kind == CXCursor_PackedAttr) {
3786 return cxstring::createRef("packed");
3787 }
3788
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003789 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003790}
3791
3792CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3793 unsigned pieceIndex,
3794 unsigned options) {
3795 if (clang_Cursor_isNull(C))
3796 return clang_getNullRange();
3797
3798 ASTContext &Ctx = getCursorContext(C);
3799
3800 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003801 const Stmt *S = getCursorStmt(C);
3802 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003803 if (pieceIndex > 0)
3804 return clang_getNullRange();
3805 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3806 }
3807
3808 return clang_getNullRange();
3809 }
3810
3811 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003812 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003813 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3814 if (pieceIndex >= ME->getNumSelectorLocs())
3815 return clang_getNullRange();
3816 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3817 }
3818 }
3819
3820 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3821 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003822 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003823 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3824 if (pieceIndex >= MD->getNumSelectorLocs())
3825 return clang_getNullRange();
3826 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3827 }
3828 }
3829
3830 if (C.kind == CXCursor_ObjCCategoryDecl ||
3831 C.kind == CXCursor_ObjCCategoryImplDecl) {
3832 if (pieceIndex > 0)
3833 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003834 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003835 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3836 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003837 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003838 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3839 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3840 }
3841
3842 if (C.kind == CXCursor_ModuleImportDecl) {
3843 if (pieceIndex > 0)
3844 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003845 if (const ImportDecl *ImportD =
3846 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003847 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3848 if (!Locs.empty())
3849 return cxloc::translateSourceRange(Ctx,
3850 SourceRange(Locs.front(), Locs.back()));
3851 }
3852 return clang_getNullRange();
3853 }
3854
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00003855 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
3856 C.kind == CXCursor_ConversionFunction) {
3857 if (pieceIndex > 0)
3858 return clang_getNullRange();
3859 if (const FunctionDecl *FD =
3860 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
3861 DeclarationNameInfo FunctionName = FD->getNameInfo();
3862 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
3863 }
3864 return clang_getNullRange();
3865 }
3866
Guy Benyei11169dd2012-12-18 14:30:41 +00003867 // FIXME: A CXCursor_InclusionDirective should give the location of the
3868 // filename, but we don't keep track of this.
3869
3870 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3871 // but we don't keep track of this.
3872
3873 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3874 // but we don't keep track of this.
3875
3876 // Default handling, give the location of the cursor.
3877
3878 if (pieceIndex > 0)
3879 return clang_getNullRange();
3880
3881 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3882 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3883 return cxloc::translateSourceRange(Ctx, Loc);
3884}
3885
Eli Bendersky44a206f2014-07-31 18:04:56 +00003886CXString clang_Cursor_getMangling(CXCursor C) {
3887 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
3888 return cxstring::createEmpty();
3889
Eli Bendersky44a206f2014-07-31 18:04:56 +00003890 // Mangling only works for functions and variables.
Eli Bendersky79759592014-08-01 15:01:10 +00003891 const Decl *D = getCursorDecl(C);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003892 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
3893 return cxstring::createEmpty();
3894
Eli Bendersky79759592014-08-01 15:01:10 +00003895 // First apply frontend mangling.
Eli Bendersky44a206f2014-07-31 18:04:56 +00003896 const NamedDecl *ND = cast<NamedDecl>(D);
Eli Bendersky79759592014-08-01 15:01:10 +00003897 ASTContext &Ctx = ND->getASTContext();
3898 std::unique_ptr<MangleContext> MC(Ctx.createMangleContext());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003899
Eli Bendersky79759592014-08-01 15:01:10 +00003900 std::string FrontendBuf;
3901 llvm::raw_string_ostream FrontendBufOS(FrontendBuf);
3902 MC->mangleName(ND, FrontendBufOS);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003903
Eli Bendersky79759592014-08-01 15:01:10 +00003904 // Now apply backend mangling.
3905 std::unique_ptr<llvm::DataLayout> DL(
3906 new llvm::DataLayout(Ctx.getTargetInfo().getTargetDescription()));
Eli Bendersky79759592014-08-01 15:01:10 +00003907
3908 std::string FinalBuf;
3909 llvm::raw_string_ostream FinalBufOS(FinalBuf);
Rafael Espindolab633d202015-06-23 13:59:36 +00003910 llvm::Mangler::getNameWithPrefix(FinalBufOS, llvm::Twine(FrontendBufOS.str()),
3911 *DL);
Eli Bendersky79759592014-08-01 15:01:10 +00003912
3913 return cxstring::createDup(FinalBufOS.str());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003914}
3915
Guy Benyei11169dd2012-12-18 14:30:41 +00003916CXString clang_getCursorDisplayName(CXCursor C) {
3917 if (!clang_isDeclaration(C.kind))
3918 return clang_getCursorSpelling(C);
3919
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003920 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003921 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003922 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003923
3924 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003925 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003926 D = FunTmpl->getTemplatedDecl();
3927
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003928 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003929 SmallString<64> Str;
3930 llvm::raw_svector_ostream OS(Str);
3931 OS << *Function;
3932 if (Function->getPrimaryTemplate())
3933 OS << "<>";
3934 OS << "(";
3935 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3936 if (I)
3937 OS << ", ";
3938 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3939 }
3940
3941 if (Function->isVariadic()) {
3942 if (Function->getNumParams())
3943 OS << ", ";
3944 OS << "...";
3945 }
3946 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003947 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003948 }
3949
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003950 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003951 SmallString<64> Str;
3952 llvm::raw_svector_ostream OS(Str);
3953 OS << *ClassTemplate;
3954 OS << "<";
3955 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3956 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3957 if (I)
3958 OS << ", ";
3959
3960 NamedDecl *Param = Params->getParam(I);
3961 if (Param->getIdentifier()) {
3962 OS << Param->getIdentifier()->getName();
3963 continue;
3964 }
3965
3966 // There is no parameter name, which makes this tricky. Try to come up
3967 // with something useful that isn't too long.
3968 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3969 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3970 else if (NonTypeTemplateParmDecl *NTTP
3971 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3972 OS << NTTP->getType().getAsString(Policy);
3973 else
3974 OS << "template<...> class";
3975 }
3976
3977 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003978 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003979 }
3980
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003981 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003982 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3983 // If the type was explicitly written, use that.
3984 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003985 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003986
Benjamin Kramer9170e912013-02-22 15:46:01 +00003987 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003988 llvm::raw_svector_ostream OS(Str);
3989 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003990 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003991 ClassSpec->getTemplateArgs().data(),
3992 ClassSpec->getTemplateArgs().size(),
3993 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003994 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003995 }
3996
3997 return clang_getCursorSpelling(C);
3998}
3999
4000CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
4001 switch (Kind) {
4002 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004003 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004004 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004005 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004006 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004007 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004008 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004009 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004010 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004011 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004012 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004013 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004014 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004015 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004016 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004017 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004018 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004019 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004020 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004021 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004022 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004023 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004024 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004025 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004026 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004027 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004028 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004029 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004030 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004031 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004032 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004033 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004034 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004035 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004036 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004037 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004038 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004039 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004040 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004041 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00004042 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004043 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004044 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004045 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004046 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004047 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004048 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004049 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004050 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004051 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004052 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004053 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004054 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004055 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004056 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004057 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004058 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004059 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004060 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004061 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004062 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004063 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004064 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004065 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004066 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004067 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004068 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004069 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004070 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004071 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004072 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004073 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004074 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004075 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004076 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004077 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004078 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004079 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004080 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004081 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004082 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004083 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004084 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004085 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004086 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004087 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004088 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004089 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004090 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004091 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004092 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004093 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004094 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004095 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004096 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004097 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004098 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004099 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004100 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004101 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004102 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004103 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004104 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004105 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004106 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004107 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004108 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004109 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004110 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004111 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004112 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004113 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004114 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004115 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004116 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004117 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004118 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004119 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004120 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004121 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004122 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004123 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004124 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004125 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004126 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004127 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004128 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004129 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00004130 case CXCursor_ObjCSelfExpr:
4131 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004132 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004133 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004134 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004135 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004136 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004137 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004138 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004139 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004140 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004141 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004142 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004143 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004144 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004145 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004146 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004147 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004148 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004149 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004150 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004151 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004152 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004153 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004154 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004155 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004156 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004157 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004158 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004159 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004160 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004161 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004162 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004163 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004164 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004165 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004166 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004167 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004168 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004169 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004170 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004171 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004172 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004173 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004174 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004175 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004176 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004177 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004178 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004179 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004180 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004181 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004182 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004183 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004184 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004185 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004186 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004187 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004188 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004189 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004190 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004191 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004192 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004193 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004194 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004195 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004196 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004197 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004198 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004199 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004200 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004201 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004202 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004203 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004204 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004205 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004206 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004207 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004208 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004209 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004210 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004211 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004212 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004213 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004214 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004215 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004216 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004217 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004218 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004219 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00004220 case CXCursor_SEHLeaveStmt:
4221 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004222 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004223 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004224 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004225 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00004226 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004227 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00004228 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004229 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00004230 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004231 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00004232 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004233 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00004234 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004235 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004236 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004237 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004238 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004239 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004240 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004241 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004242 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004243 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004244 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004245 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004246 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004247 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004248 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004249 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004250 case CXCursor_PackedAttr:
4251 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00004252 case CXCursor_PureAttr:
4253 return cxstring::createRef("attribute(pure)");
4254 case CXCursor_ConstAttr:
4255 return cxstring::createRef("attribute(const)");
4256 case CXCursor_NoDuplicateAttr:
4257 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00004258 case CXCursor_CUDAConstantAttr:
4259 return cxstring::createRef("attribute(constant)");
4260 case CXCursor_CUDADeviceAttr:
4261 return cxstring::createRef("attribute(device)");
4262 case CXCursor_CUDAGlobalAttr:
4263 return cxstring::createRef("attribute(global)");
4264 case CXCursor_CUDAHostAttr:
4265 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00004266 case CXCursor_CUDASharedAttr:
4267 return cxstring::createRef("attribute(shared)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004268 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004269 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004270 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004271 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00004272 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004273 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004274 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004275 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004276 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004277 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00004278 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004279 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00004280 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004281 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004282 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004283 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004284 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004285 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004286 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004287 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004288 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004289 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004290 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004291 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004292 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004293 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004294 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004295 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004296 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004297 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004298 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004299 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004300 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004301 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004302 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004303 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004304 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004305 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004306 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004307 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004308 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004309 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004310 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004311 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004312 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004313 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004314 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004315 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004316 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004317 return cxstring::createRef("OMPParallelDirective");
4318 case CXCursor_OMPSimdDirective:
4319 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004320 case CXCursor_OMPForDirective:
4321 return cxstring::createRef("OMPForDirective");
Alexander Musmanf82886e2014-09-18 05:12:34 +00004322 case CXCursor_OMPForSimdDirective:
4323 return cxstring::createRef("OMPForSimdDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004324 case CXCursor_OMPSectionsDirective:
4325 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004326 case CXCursor_OMPSectionDirective:
4327 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004328 case CXCursor_OMPSingleDirective:
4329 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004330 case CXCursor_OMPMasterDirective:
4331 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004332 case CXCursor_OMPCriticalDirective:
4333 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004334 case CXCursor_OMPParallelForDirective:
4335 return cxstring::createRef("OMPParallelForDirective");
Alexander Musmane4e893b2014-09-23 09:33:00 +00004336 case CXCursor_OMPParallelForSimdDirective:
4337 return cxstring::createRef("OMPParallelForSimdDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004338 case CXCursor_OMPParallelSectionsDirective:
4339 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004340 case CXCursor_OMPTaskDirective:
4341 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004342 case CXCursor_OMPTaskyieldDirective:
4343 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004344 case CXCursor_OMPBarrierDirective:
4345 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004346 case CXCursor_OMPTaskwaitDirective:
4347 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00004348 case CXCursor_OMPTaskgroupDirective:
4349 return cxstring::createRef("OMPTaskgroupDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00004350 case CXCursor_OMPFlushDirective:
4351 return cxstring::createRef("OMPFlushDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004352 case CXCursor_OMPOrderedDirective:
4353 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00004354 case CXCursor_OMPAtomicDirective:
4355 return cxstring::createRef("OMPAtomicDirective");
Alexey Bataev0bd520b2014-09-19 08:19:49 +00004356 case CXCursor_OMPTargetDirective:
4357 return cxstring::createRef("OMPTargetDirective");
Michael Wong65f367f2015-07-21 13:44:28 +00004358 case CXCursor_OMPTargetDataDirective:
4359 return cxstring::createRef("OMPTargetDataDirective");
Alexey Bataev13314bf2014-10-09 04:18:56 +00004360 case CXCursor_OMPTeamsDirective:
4361 return cxstring::createRef("OMPTeamsDirective");
Alexey Bataev6d4ed052015-07-01 06:57:41 +00004362 case CXCursor_OMPCancellationPointDirective:
4363 return cxstring::createRef("OMPCancellationPointDirective");
Alexey Bataev80909872015-07-02 11:25:17 +00004364 case CXCursor_OMPCancelDirective:
4365 return cxstring::createRef("OMPCancelDirective");
Francisco Lopes da Silva975a9f62015-01-21 16:24:11 +00004366 case CXCursor_OverloadCandidate:
4367 return cxstring::createRef("OverloadCandidate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004368 }
4369
4370 llvm_unreachable("Unhandled CXCursorKind");
4371}
4372
4373struct GetCursorData {
4374 SourceLocation TokenBeginLoc;
4375 bool PointsAtMacroArgExpansion;
4376 bool VisitedObjCPropertyImplDecl;
4377 SourceLocation VisitedDeclaratorDeclStartLoc;
4378 CXCursor &BestCursor;
4379
4380 GetCursorData(SourceManager &SM,
4381 SourceLocation tokenBegin, CXCursor &outputCursor)
4382 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4383 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4384 VisitedObjCPropertyImplDecl = false;
4385 }
4386};
4387
4388static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4389 CXCursor parent,
4390 CXClientData client_data) {
4391 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4392 CXCursor *BestCursor = &Data->BestCursor;
4393
4394 // If we point inside a macro argument we should provide info of what the
4395 // token is so use the actual cursor, don't replace it with a macro expansion
4396 // cursor.
4397 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4398 return CXChildVisit_Recurse;
4399
4400 if (clang_isDeclaration(cursor.kind)) {
4401 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004402 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004403 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4404 if (MD->isImplicit())
4405 return CXChildVisit_Break;
4406
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004407 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004408 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4409 // Check that when we have multiple @class references in the same line,
4410 // that later ones do not override the previous ones.
4411 // If we have:
4412 // @class Foo, Bar;
4413 // source ranges for both start at '@', so 'Bar' will end up overriding
4414 // 'Foo' even though the cursor location was at 'Foo'.
4415 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4416 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004417 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004418 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4419 if (PrevID != ID &&
4420 !PrevID->isThisDeclarationADefinition() &&
4421 !ID->isThisDeclarationADefinition())
4422 return CXChildVisit_Break;
4423 }
4424
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004425 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004426 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4427 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4428 // Check that when we have multiple declarators in the same line,
4429 // that later ones do not override the previous ones.
4430 // If we have:
4431 // int Foo, Bar;
4432 // source ranges for both start at 'int', so 'Bar' will end up overriding
4433 // 'Foo' even though the cursor location was at 'Foo'.
4434 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4435 return CXChildVisit_Break;
4436 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4437
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004438 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004439 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4440 (void)PropImp;
4441 // Check that when we have multiple @synthesize in the same line,
4442 // that later ones do not override the previous ones.
4443 // If we have:
4444 // @synthesize Foo, Bar;
4445 // source ranges for both start at '@', so 'Bar' will end up overriding
4446 // 'Foo' even though the cursor location was at 'Foo'.
4447 if (Data->VisitedObjCPropertyImplDecl)
4448 return CXChildVisit_Break;
4449 Data->VisitedObjCPropertyImplDecl = true;
4450 }
4451 }
4452
4453 if (clang_isExpression(cursor.kind) &&
4454 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004455 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004456 // Avoid having the cursor of an expression replace the declaration cursor
4457 // when the expression source range overlaps the declaration range.
4458 // This can happen for C++ constructor expressions whose range generally
4459 // include the variable declaration, e.g.:
4460 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4461 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4462 D->getLocation() == Data->TokenBeginLoc)
4463 return CXChildVisit_Break;
4464 }
4465 }
4466
4467 // If our current best cursor is the construction of a temporary object,
4468 // don't replace that cursor with a type reference, because we want
4469 // clang_getCursor() to point at the constructor.
4470 if (clang_isExpression(BestCursor->kind) &&
4471 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4472 cursor.kind == CXCursor_TypeRef) {
4473 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4474 // as having the actual point on the type reference.
4475 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4476 return CXChildVisit_Recurse;
4477 }
Douglas Gregore9d95f12015-07-07 03:57:35 +00004478
4479 // If we already have an Objective-C superclass reference, don't
4480 // update it further.
4481 if (BestCursor->kind == CXCursor_ObjCSuperClassRef)
4482 return CXChildVisit_Break;
4483
Guy Benyei11169dd2012-12-18 14:30:41 +00004484 *BestCursor = cursor;
4485 return CXChildVisit_Recurse;
4486}
4487
4488CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004489 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004490 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004491 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004492 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004493
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004494 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004495 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4496
4497 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4498 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4499
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004500 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004501 CXFile SearchFile;
4502 unsigned SearchLine, SearchColumn;
4503 CXFile ResultFile;
4504 unsigned ResultLine, ResultColumn;
4505 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4506 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4507 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004508
4509 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4510 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004511 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004512 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004513 SearchFileName = clang_getFileName(SearchFile);
4514 ResultFileName = clang_getFileName(ResultFile);
4515 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4516 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004517 *Log << llvm::format("(%s:%d:%d) = %s",
4518 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4519 clang_getCString(KindSpelling))
4520 << llvm::format("(%s:%d:%d):%s%s",
4521 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4522 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004523 clang_disposeString(SearchFileName);
4524 clang_disposeString(ResultFileName);
4525 clang_disposeString(KindSpelling);
4526 clang_disposeString(USR);
4527
4528 CXCursor Definition = clang_getCursorDefinition(Result);
4529 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4530 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4531 CXString DefinitionKindSpelling
4532 = clang_getCursorKindSpelling(Definition.kind);
4533 CXFile DefinitionFile;
4534 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004535 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004536 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004537 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004538 *Log << llvm::format(" -> %s(%s:%d:%d)",
4539 clang_getCString(DefinitionKindSpelling),
4540 clang_getCString(DefinitionFileName),
4541 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004542 clang_disposeString(DefinitionFileName);
4543 clang_disposeString(DefinitionKindSpelling);
4544 }
4545 }
4546
4547 return Result;
4548}
4549
4550CXCursor clang_getNullCursor(void) {
4551 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4552}
4553
4554unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004555 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4556 // can't set consistently. For example, when visiting a DeclStmt we will set
4557 // it but we don't set it on the result of clang_getCursorDefinition for
4558 // a reference of the same declaration.
4559 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4560 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4561 // to provide that kind of info.
4562 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004563 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004564 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004565 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004566
Guy Benyei11169dd2012-12-18 14:30:41 +00004567 return X == Y;
4568}
4569
4570unsigned clang_hashCursor(CXCursor C) {
4571 unsigned Index = 0;
4572 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4573 Index = 1;
4574
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004575 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004576 std::make_pair(C.kind, C.data[Index]));
4577}
4578
4579unsigned clang_isInvalid(enum CXCursorKind K) {
4580 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4581}
4582
4583unsigned clang_isDeclaration(enum CXCursorKind K) {
4584 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4585 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4586}
4587
4588unsigned clang_isReference(enum CXCursorKind K) {
4589 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4590}
4591
4592unsigned clang_isExpression(enum CXCursorKind K) {
4593 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4594}
4595
4596unsigned clang_isStatement(enum CXCursorKind K) {
4597 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4598}
4599
4600unsigned clang_isAttribute(enum CXCursorKind K) {
4601 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4602}
4603
4604unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4605 return K == CXCursor_TranslationUnit;
4606}
4607
4608unsigned clang_isPreprocessing(enum CXCursorKind K) {
4609 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4610}
4611
4612unsigned clang_isUnexposed(enum CXCursorKind K) {
4613 switch (K) {
4614 case CXCursor_UnexposedDecl:
4615 case CXCursor_UnexposedExpr:
4616 case CXCursor_UnexposedStmt:
4617 case CXCursor_UnexposedAttr:
4618 return true;
4619 default:
4620 return false;
4621 }
4622}
4623
4624CXCursorKind clang_getCursorKind(CXCursor C) {
4625 return C.kind;
4626}
4627
4628CXSourceLocation clang_getCursorLocation(CXCursor C) {
4629 if (clang_isReference(C.kind)) {
4630 switch (C.kind) {
4631 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004632 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004633 = getCursorObjCSuperClassRef(C);
4634 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4635 }
4636
4637 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004638 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004639 = getCursorObjCProtocolRef(C);
4640 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4641 }
4642
4643 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004644 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004645 = getCursorObjCClassRef(C);
4646 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4647 }
4648
4649 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004650 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004651 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4652 }
4653
4654 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004655 std::pair<const TemplateDecl *, SourceLocation> P =
4656 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004657 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4658 }
4659
4660 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004661 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004662 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4663 }
4664
4665 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004666 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004667 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4668 }
4669
4670 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004671 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004672 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4673 }
4674
4675 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004676 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004677 if (!BaseSpec)
4678 return clang_getNullLocation();
4679
4680 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4681 return cxloc::translateSourceLocation(getCursorContext(C),
4682 TSInfo->getTypeLoc().getBeginLoc());
4683
4684 return cxloc::translateSourceLocation(getCursorContext(C),
4685 BaseSpec->getLocStart());
4686 }
4687
4688 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004689 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004690 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4691 }
4692
4693 case CXCursor_OverloadedDeclRef:
4694 return cxloc::translateSourceLocation(getCursorContext(C),
4695 getCursorOverloadedDeclRef(C).second);
4696
4697 default:
4698 // FIXME: Need a way to enumerate all non-reference cases.
4699 llvm_unreachable("Missed a reference kind");
4700 }
4701 }
4702
4703 if (clang_isExpression(C.kind))
4704 return cxloc::translateSourceLocation(getCursorContext(C),
4705 getLocationFromExpr(getCursorExpr(C)));
4706
4707 if (clang_isStatement(C.kind))
4708 return cxloc::translateSourceLocation(getCursorContext(C),
4709 getCursorStmt(C)->getLocStart());
4710
4711 if (C.kind == CXCursor_PreprocessingDirective) {
4712 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4713 return cxloc::translateSourceLocation(getCursorContext(C), L);
4714 }
4715
4716 if (C.kind == CXCursor_MacroExpansion) {
4717 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004718 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004719 return cxloc::translateSourceLocation(getCursorContext(C), L);
4720 }
4721
4722 if (C.kind == CXCursor_MacroDefinition) {
4723 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4724 return cxloc::translateSourceLocation(getCursorContext(C), L);
4725 }
4726
4727 if (C.kind == CXCursor_InclusionDirective) {
4728 SourceLocation L
4729 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4730 return cxloc::translateSourceLocation(getCursorContext(C), L);
4731 }
4732
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004733 if (clang_isAttribute(C.kind)) {
4734 SourceLocation L
4735 = cxcursor::getCursorAttr(C)->getLocation();
4736 return cxloc::translateSourceLocation(getCursorContext(C), L);
4737 }
4738
Guy Benyei11169dd2012-12-18 14:30:41 +00004739 if (!clang_isDeclaration(C.kind))
4740 return clang_getNullLocation();
4741
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004742 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004743 if (!D)
4744 return clang_getNullLocation();
4745
4746 SourceLocation Loc = D->getLocation();
4747 // FIXME: Multiple variables declared in a single declaration
4748 // currently lack the information needed to correctly determine their
4749 // ranges when accounting for the type-specifier. We use context
4750 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4751 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004752 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004753 if (!cxcursor::isFirstInDeclGroup(C))
4754 Loc = VD->getLocation();
4755 }
4756
4757 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004758 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004759 Loc = MD->getSelectorStartLoc();
4760
4761 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4762}
4763
4764} // end extern "C"
4765
4766CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4767 assert(TU);
4768
4769 // Guard against an invalid SourceLocation, or we may assert in one
4770 // of the following calls.
4771 if (SLoc.isInvalid())
4772 return clang_getNullCursor();
4773
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004774 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004775
4776 // Translate the given source location to make it point at the beginning of
4777 // the token under the cursor.
4778 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4779 CXXUnit->getASTContext().getLangOpts());
4780
4781 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4782 if (SLoc.isValid()) {
4783 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4784 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4785 /*VisitPreprocessorLast=*/true,
4786 /*VisitIncludedEntities=*/false,
4787 SourceLocation(SLoc));
4788 CursorVis.visitFileRegion();
4789 }
4790
4791 return Result;
4792}
4793
4794static SourceRange getRawCursorExtent(CXCursor C) {
4795 if (clang_isReference(C.kind)) {
4796 switch (C.kind) {
4797 case CXCursor_ObjCSuperClassRef:
4798 return getCursorObjCSuperClassRef(C).second;
4799
4800 case CXCursor_ObjCProtocolRef:
4801 return getCursorObjCProtocolRef(C).second;
4802
4803 case CXCursor_ObjCClassRef:
4804 return getCursorObjCClassRef(C).second;
4805
4806 case CXCursor_TypeRef:
4807 return getCursorTypeRef(C).second;
4808
4809 case CXCursor_TemplateRef:
4810 return getCursorTemplateRef(C).second;
4811
4812 case CXCursor_NamespaceRef:
4813 return getCursorNamespaceRef(C).second;
4814
4815 case CXCursor_MemberRef:
4816 return getCursorMemberRef(C).second;
4817
4818 case CXCursor_CXXBaseSpecifier:
4819 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4820
4821 case CXCursor_LabelRef:
4822 return getCursorLabelRef(C).second;
4823
4824 case CXCursor_OverloadedDeclRef:
4825 return getCursorOverloadedDeclRef(C).second;
4826
4827 case CXCursor_VariableRef:
4828 return getCursorVariableRef(C).second;
4829
4830 default:
4831 // FIXME: Need a way to enumerate all non-reference cases.
4832 llvm_unreachable("Missed a reference kind");
4833 }
4834 }
4835
4836 if (clang_isExpression(C.kind))
4837 return getCursorExpr(C)->getSourceRange();
4838
4839 if (clang_isStatement(C.kind))
4840 return getCursorStmt(C)->getSourceRange();
4841
4842 if (clang_isAttribute(C.kind))
4843 return getCursorAttr(C)->getRange();
4844
4845 if (C.kind == CXCursor_PreprocessingDirective)
4846 return cxcursor::getCursorPreprocessingDirective(C);
4847
4848 if (C.kind == CXCursor_MacroExpansion) {
4849 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004850 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004851 return TU->mapRangeFromPreamble(Range);
4852 }
4853
4854 if (C.kind == CXCursor_MacroDefinition) {
4855 ASTUnit *TU = getCursorASTUnit(C);
4856 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4857 return TU->mapRangeFromPreamble(Range);
4858 }
4859
4860 if (C.kind == CXCursor_InclusionDirective) {
4861 ASTUnit *TU = getCursorASTUnit(C);
4862 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4863 return TU->mapRangeFromPreamble(Range);
4864 }
4865
4866 if (C.kind == CXCursor_TranslationUnit) {
4867 ASTUnit *TU = getCursorASTUnit(C);
4868 FileID MainID = TU->getSourceManager().getMainFileID();
4869 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4870 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4871 return SourceRange(Start, End);
4872 }
4873
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 // FIXME: Multiple variables declared in a single declaration
4881 // currently lack the information needed to correctly determine their
4882 // ranges when accounting for the type-specifier. We use context
4883 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4884 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004885 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004886 if (!cxcursor::isFirstInDeclGroup(C))
4887 R.setBegin(VD->getLocation());
4888 }
4889 return R;
4890 }
4891 return SourceRange();
4892}
4893
4894/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4895/// the decl-specifier-seq for declarations.
4896static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4897 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004898 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004899 if (!D)
4900 return SourceRange();
4901
4902 SourceRange R = D->getSourceRange();
4903
4904 // Adjust the start of the location for declarations preceded by
4905 // declaration specifiers.
4906 SourceLocation StartLoc;
4907 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4908 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4909 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004910 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004911 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4912 StartLoc = TI->getTypeLoc().getLocStart();
4913 }
4914
4915 if (StartLoc.isValid() && R.getBegin().isValid() &&
4916 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4917 R.setBegin(StartLoc);
4918
4919 // FIXME: Multiple variables declared in a single declaration
4920 // currently lack the information needed to correctly determine their
4921 // ranges when accounting for the type-specifier. We use context
4922 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4923 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004924 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004925 if (!cxcursor::isFirstInDeclGroup(C))
4926 R.setBegin(VD->getLocation());
4927 }
4928
4929 return R;
4930 }
4931
4932 return getRawCursorExtent(C);
4933}
4934
4935extern "C" {
4936
4937CXSourceRange clang_getCursorExtent(CXCursor C) {
4938 SourceRange R = getRawCursorExtent(C);
4939 if (R.isInvalid())
4940 return clang_getNullRange();
4941
4942 return cxloc::translateSourceRange(getCursorContext(C), R);
4943}
4944
4945CXCursor clang_getCursorReferenced(CXCursor C) {
4946 if (clang_isInvalid(C.kind))
4947 return clang_getNullCursor();
4948
4949 CXTranslationUnit tu = getCursorTU(C);
4950 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004951 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004952 if (!D)
4953 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004954 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004955 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004956 if (const ObjCPropertyImplDecl *PropImpl =
4957 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004958 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4959 return MakeCXCursor(Property, tu);
4960
4961 return C;
4962 }
4963
4964 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004965 const Expr *E = getCursorExpr(C);
4966 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004967 if (D) {
4968 CXCursor declCursor = MakeCXCursor(D, tu);
4969 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4970 declCursor);
4971 return declCursor;
4972 }
4973
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004974 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004975 return MakeCursorOverloadedDeclRef(Ovl, tu);
4976
4977 return clang_getNullCursor();
4978 }
4979
4980 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004981 const Stmt *S = getCursorStmt(C);
4982 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004983 if (LabelDecl *label = Goto->getLabel())
4984 if (LabelStmt *labelS = label->getStmt())
4985 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4986
4987 return clang_getNullCursor();
4988 }
Richard Smith66a81862015-05-04 02:25:31 +00004989
Guy Benyei11169dd2012-12-18 14:30:41 +00004990 if (C.kind == CXCursor_MacroExpansion) {
Richard Smith66a81862015-05-04 02:25:31 +00004991 if (const MacroDefinitionRecord *Def =
4992 getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004993 return MakeMacroDefinitionCursor(Def, tu);
4994 }
4995
4996 if (!clang_isReference(C.kind))
4997 return clang_getNullCursor();
4998
4999 switch (C.kind) {
5000 case CXCursor_ObjCSuperClassRef:
5001 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
5002
5003 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005004 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
5005 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005006 return MakeCXCursor(Def, tu);
5007
5008 return MakeCXCursor(Prot, tu);
5009 }
5010
5011 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005012 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
5013 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005014 return MakeCXCursor(Def, tu);
5015
5016 return MakeCXCursor(Class, tu);
5017 }
5018
5019 case CXCursor_TypeRef:
5020 return MakeCXCursor(getCursorTypeRef(C).first, tu );
5021
5022 case CXCursor_TemplateRef:
5023 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
5024
5025 case CXCursor_NamespaceRef:
5026 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
5027
5028 case CXCursor_MemberRef:
5029 return MakeCXCursor(getCursorMemberRef(C).first, tu );
5030
5031 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005032 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005033 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
5034 tu ));
5035 }
5036
5037 case CXCursor_LabelRef:
5038 // FIXME: We end up faking the "parent" declaration here because we
5039 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005040 return MakeCXCursor(getCursorLabelRef(C).first,
5041 cxtu::getASTUnit(tu)->getASTContext()
5042 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00005043 tu);
5044
5045 case CXCursor_OverloadedDeclRef:
5046 return C;
5047
5048 case CXCursor_VariableRef:
5049 return MakeCXCursor(getCursorVariableRef(C).first, tu);
5050
5051 default:
5052 // We would prefer to enumerate all non-reference cursor kinds here.
5053 llvm_unreachable("Unhandled reference cursor kind");
5054 }
5055}
5056
5057CXCursor clang_getCursorDefinition(CXCursor C) {
5058 if (clang_isInvalid(C.kind))
5059 return clang_getNullCursor();
5060
5061 CXTranslationUnit TU = getCursorTU(C);
5062
5063 bool WasReference = false;
5064 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
5065 C = clang_getCursorReferenced(C);
5066 WasReference = true;
5067 }
5068
5069 if (C.kind == CXCursor_MacroExpansion)
5070 return clang_getCursorReferenced(C);
5071
5072 if (!clang_isDeclaration(C.kind))
5073 return clang_getNullCursor();
5074
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005075 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005076 if (!D)
5077 return clang_getNullCursor();
5078
5079 switch (D->getKind()) {
5080 // Declaration kinds that don't really separate the notions of
5081 // declaration and definition.
5082 case Decl::Namespace:
5083 case Decl::Typedef:
5084 case Decl::TypeAlias:
5085 case Decl::TypeAliasTemplate:
5086 case Decl::TemplateTypeParm:
5087 case Decl::EnumConstant:
5088 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00005089 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005090 case Decl::IndirectField:
5091 case Decl::ObjCIvar:
5092 case Decl::ObjCAtDefsField:
5093 case Decl::ImplicitParam:
5094 case Decl::ParmVar:
5095 case Decl::NonTypeTemplateParm:
5096 case Decl::TemplateTemplateParm:
5097 case Decl::ObjCCategoryImpl:
5098 case Decl::ObjCImplementation:
5099 case Decl::AccessSpec:
5100 case Decl::LinkageSpec:
5101 case Decl::ObjCPropertyImpl:
5102 case Decl::FileScopeAsm:
5103 case Decl::StaticAssert:
5104 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00005105 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00005106 case Decl::Label: // FIXME: Is this right??
5107 case Decl::ClassScopeFunctionSpecialization:
5108 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00005109 case Decl::OMPThreadPrivate:
Douglas Gregor85f3f952015-07-07 03:57:15 +00005110 case Decl::ObjCTypeParam:
Guy Benyei11169dd2012-12-18 14:30:41 +00005111 return C;
5112
5113 // Declaration kinds that don't make any sense here, but are
5114 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00005115 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005116 case Decl::TranslationUnit:
Richard Smithf19e1272015-03-07 00:04:49 +00005117 case Decl::ExternCContext:
Guy Benyei11169dd2012-12-18 14:30:41 +00005118 break;
5119
5120 // Declaration kinds for which the definition is not resolvable.
5121 case Decl::UnresolvedUsingTypename:
5122 case Decl::UnresolvedUsingValue:
5123 break;
5124
5125 case Decl::UsingDirective:
5126 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
5127 TU);
5128
5129 case Decl::NamespaceAlias:
5130 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
5131
5132 case Decl::Enum:
5133 case Decl::Record:
5134 case Decl::CXXRecord:
5135 case Decl::ClassTemplateSpecialization:
5136 case Decl::ClassTemplatePartialSpecialization:
5137 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
5138 return MakeCXCursor(Def, TU);
5139 return clang_getNullCursor();
5140
5141 case Decl::Function:
5142 case Decl::CXXMethod:
5143 case Decl::CXXConstructor:
5144 case Decl::CXXDestructor:
5145 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00005146 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005147 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00005148 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005149 return clang_getNullCursor();
5150 }
5151
Larisse Voufo39a1e502013-08-06 01:03:05 +00005152 case Decl::Var:
5153 case Decl::VarTemplateSpecialization:
5154 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00005155 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005156 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005157 return MakeCXCursor(Def, TU);
5158 return clang_getNullCursor();
5159 }
5160
5161 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00005162 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005163 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
5164 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
5165 return clang_getNullCursor();
5166 }
5167
5168 case Decl::ClassTemplate: {
5169 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
5170 ->getDefinition())
5171 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
5172 TU);
5173 return clang_getNullCursor();
5174 }
5175
Larisse Voufo39a1e502013-08-06 01:03:05 +00005176 case Decl::VarTemplate: {
5177 if (VarDecl *Def =
5178 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
5179 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
5180 return clang_getNullCursor();
5181 }
5182
Guy Benyei11169dd2012-12-18 14:30:41 +00005183 case Decl::Using:
5184 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
5185 D->getLocation(), TU);
5186
5187 case Decl::UsingShadow:
5188 return clang_getCursorDefinition(
5189 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
5190 TU));
5191
5192 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005193 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005194 if (Method->isThisDeclarationADefinition())
5195 return C;
5196
5197 // Dig out the method definition in the associated
5198 // @implementation, if we have it.
5199 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005200 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005201 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
5202 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
5203 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
5204 Method->isInstanceMethod()))
5205 if (Def->isThisDeclarationADefinition())
5206 return MakeCXCursor(Def, TU);
5207
5208 return clang_getNullCursor();
5209 }
5210
5211 case Decl::ObjCCategory:
5212 if (ObjCCategoryImplDecl *Impl
5213 = cast<ObjCCategoryDecl>(D)->getImplementation())
5214 return MakeCXCursor(Impl, TU);
5215 return clang_getNullCursor();
5216
5217 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005218 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005219 return MakeCXCursor(Def, TU);
5220 return clang_getNullCursor();
5221
5222 case Decl::ObjCInterface: {
5223 // There are two notions of a "definition" for an Objective-C
5224 // class: the interface and its implementation. When we resolved a
5225 // reference to an Objective-C class, produce the @interface as
5226 // the definition; when we were provided with the interface,
5227 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005228 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005229 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005230 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005231 return MakeCXCursor(Def, TU);
5232 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
5233 return MakeCXCursor(Impl, TU);
5234 return clang_getNullCursor();
5235 }
5236
5237 case Decl::ObjCProperty:
5238 // FIXME: We don't really know where to find the
5239 // ObjCPropertyImplDecls that implement this property.
5240 return clang_getNullCursor();
5241
5242 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005243 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005244 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005245 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005246 return MakeCXCursor(Def, TU);
5247
5248 return clang_getNullCursor();
5249
5250 case Decl::Friend:
5251 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
5252 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5253 return clang_getNullCursor();
5254
5255 case Decl::FriendTemplate:
5256 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
5257 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5258 return clang_getNullCursor();
5259 }
5260
5261 return clang_getNullCursor();
5262}
5263
5264unsigned clang_isCursorDefinition(CXCursor C) {
5265 if (!clang_isDeclaration(C.kind))
5266 return 0;
5267
5268 return clang_getCursorDefinition(C) == C;
5269}
5270
5271CXCursor clang_getCanonicalCursor(CXCursor C) {
5272 if (!clang_isDeclaration(C.kind))
5273 return C;
5274
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005275 if (const Decl *D = getCursorDecl(C)) {
5276 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005277 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5278 return MakeCXCursor(CatD, getCursorTU(C));
5279
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005280 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5281 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00005282 return MakeCXCursor(IFD, getCursorTU(C));
5283
5284 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5285 }
5286
5287 return C;
5288}
5289
5290int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5291 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5292}
5293
5294unsigned clang_getNumOverloadedDecls(CXCursor C) {
5295 if (C.kind != CXCursor_OverloadedDeclRef)
5296 return 0;
5297
5298 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).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 E->getNumDecls();
5301
5302 if (OverloadedTemplateStorage *S
5303 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5304 return S->size();
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 return Using->shadow_size();
5309
5310 return 0;
5311}
5312
5313CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5314 if (cursor.kind != CXCursor_OverloadedDeclRef)
5315 return clang_getNullCursor();
5316
5317 if (index >= clang_getNumOverloadedDecls(cursor))
5318 return clang_getNullCursor();
5319
5320 CXTranslationUnit TU = getCursorTU(cursor);
5321 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005322 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005323 return MakeCXCursor(E->decls_begin()[index], TU);
5324
5325 if (OverloadedTemplateStorage *S
5326 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5327 return MakeCXCursor(S->begin()[index], TU);
5328
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005329 const Decl *D = Storage.get<const Decl *>();
5330 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005331 // FIXME: This is, unfortunately, linear time.
5332 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5333 std::advance(Pos, index);
5334 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5335 }
5336
5337 return clang_getNullCursor();
5338}
5339
5340void clang_getDefinitionSpellingAndExtent(CXCursor C,
5341 const char **startBuf,
5342 const char **endBuf,
5343 unsigned *startLine,
5344 unsigned *startColumn,
5345 unsigned *endLine,
5346 unsigned *endColumn) {
5347 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005348 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005349 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5350
5351 SourceManager &SM = FD->getASTContext().getSourceManager();
5352 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5353 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5354 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5355 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5356 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5357 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5358}
5359
5360
5361CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5362 unsigned PieceIndex) {
5363 RefNamePieces Pieces;
5364
5365 switch (C.kind) {
5366 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005367 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005368 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5369 E->getQualifierLoc().getSourceRange());
5370 break;
5371
5372 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005373 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005374 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
5375 E->getQualifierLoc().getSourceRange(),
5376 E->getOptionalExplicitTemplateArgs());
5377 break;
5378
5379 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005380 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005381 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005382 const Expr *Callee = OCE->getCallee();
5383 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005384 Callee = ICE->getSubExpr();
5385
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005386 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005387 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5388 DRE->getQualifierLoc().getSourceRange());
5389 }
5390 break;
5391
5392 default:
5393 break;
5394 }
5395
5396 if (Pieces.empty()) {
5397 if (PieceIndex == 0)
5398 return clang_getCursorExtent(C);
5399 } else if (PieceIndex < Pieces.size()) {
5400 SourceRange R = Pieces[PieceIndex];
5401 if (R.isValid())
5402 return cxloc::translateSourceRange(getCursorContext(C), R);
5403 }
5404
5405 return clang_getNullRange();
5406}
5407
5408void clang_enableStackTraces(void) {
5409 llvm::sys::PrintStackTraceOnErrorSignal();
5410}
5411
5412void clang_executeOnThread(void (*fn)(void*), void *user_data,
5413 unsigned stack_size) {
5414 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5415}
5416
5417} // end: extern "C"
5418
5419//===----------------------------------------------------------------------===//
5420// Token-based Operations.
5421//===----------------------------------------------------------------------===//
5422
5423/* CXToken layout:
5424 * int_data[0]: a CXTokenKind
5425 * int_data[1]: starting token location
5426 * int_data[2]: token length
5427 * int_data[3]: reserved
5428 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5429 * otherwise unused.
5430 */
5431extern "C" {
5432
5433CXTokenKind clang_getTokenKind(CXToken CXTok) {
5434 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5435}
5436
5437CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5438 switch (clang_getTokenKind(CXTok)) {
5439 case CXToken_Identifier:
5440 case CXToken_Keyword:
5441 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005442 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005443 ->getNameStart());
5444
5445 case CXToken_Literal: {
5446 // We have stashed the starting pointer in the ptr_data field. Use it.
5447 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005448 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005449 }
5450
5451 case CXToken_Punctuation:
5452 case CXToken_Comment:
5453 break;
5454 }
5455
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005456 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005457 LOG_BAD_TU(TU);
5458 return cxstring::createEmpty();
5459 }
5460
Guy Benyei11169dd2012-12-18 14:30:41 +00005461 // We have to find the starting buffer pointer the hard way, by
5462 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005463 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005464 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005465 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005466
5467 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5468 std::pair<FileID, unsigned> LocInfo
5469 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5470 bool Invalid = false;
5471 StringRef Buffer
5472 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5473 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005474 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005475
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005476 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005477}
5478
5479CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005480 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005481 LOG_BAD_TU(TU);
5482 return clang_getNullLocation();
5483 }
5484
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005485 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005486 if (!CXXUnit)
5487 return clang_getNullLocation();
5488
5489 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5490 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5491}
5492
5493CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005494 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005495 LOG_BAD_TU(TU);
5496 return clang_getNullRange();
5497 }
5498
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005499 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005500 if (!CXXUnit)
5501 return clang_getNullRange();
5502
5503 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5504 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5505}
5506
5507static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5508 SmallVectorImpl<CXToken> &CXTokens) {
5509 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5510 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005511 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005512 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005513 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005514
5515 // Cannot tokenize across files.
5516 if (BeginLocInfo.first != EndLocInfo.first)
5517 return;
5518
5519 // Create a lexer
5520 bool Invalid = false;
5521 StringRef Buffer
5522 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5523 if (Invalid)
5524 return;
5525
5526 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5527 CXXUnit->getASTContext().getLangOpts(),
5528 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5529 Lex.SetCommentRetentionState(true);
5530
5531 // Lex tokens until we hit the end of the range.
5532 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5533 Token Tok;
5534 bool previousWasAt = false;
5535 do {
5536 // Lex the next token
5537 Lex.LexFromRawLexer(Tok);
5538 if (Tok.is(tok::eof))
5539 break;
5540
5541 // Initialize the CXToken.
5542 CXToken CXTok;
5543
5544 // - Common fields
5545 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5546 CXTok.int_data[2] = Tok.getLength();
5547 CXTok.int_data[3] = 0;
5548
5549 // - Kind-specific fields
5550 if (Tok.isLiteral()) {
5551 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005552 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005553 } else if (Tok.is(tok::raw_identifier)) {
5554 // Lookup the identifier to determine whether we have a keyword.
5555 IdentifierInfo *II
5556 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5557
5558 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5559 CXTok.int_data[0] = CXToken_Keyword;
5560 }
5561 else {
5562 CXTok.int_data[0] = Tok.is(tok::identifier)
5563 ? CXToken_Identifier
5564 : CXToken_Keyword;
5565 }
5566 CXTok.ptr_data = II;
5567 } else if (Tok.is(tok::comment)) {
5568 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005569 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005570 } else {
5571 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005572 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005573 }
5574 CXTokens.push_back(CXTok);
5575 previousWasAt = Tok.is(tok::at);
5576 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5577}
5578
5579void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5580 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005581 LOG_FUNC_SECTION {
5582 *Log << TU << ' ' << Range;
5583 }
5584
Guy Benyei11169dd2012-12-18 14:30:41 +00005585 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005586 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005587 if (NumTokens)
5588 *NumTokens = 0;
5589
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005590 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005591 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005592 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005593 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005594
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005595 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005596 if (!CXXUnit || !Tokens || !NumTokens)
5597 return;
5598
5599 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5600
5601 SourceRange R = cxloc::translateCXSourceRange(Range);
5602 if (R.isInvalid())
5603 return;
5604
5605 SmallVector<CXToken, 32> CXTokens;
5606 getTokens(CXXUnit, R, CXTokens);
5607
5608 if (CXTokens.empty())
5609 return;
5610
5611 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5612 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5613 *NumTokens = CXTokens.size();
5614}
5615
5616void clang_disposeTokens(CXTranslationUnit TU,
5617 CXToken *Tokens, unsigned NumTokens) {
5618 free(Tokens);
5619}
5620
5621} // end: extern "C"
5622
5623//===----------------------------------------------------------------------===//
5624// Token annotation APIs.
5625//===----------------------------------------------------------------------===//
5626
Guy Benyei11169dd2012-12-18 14:30:41 +00005627static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5628 CXCursor parent,
5629 CXClientData client_data);
5630static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5631 CXClientData client_data);
5632
5633namespace {
5634class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005635 CXToken *Tokens;
5636 CXCursor *Cursors;
5637 unsigned NumTokens;
5638 unsigned TokIdx;
5639 unsigned PreprocessingTokIdx;
5640 CursorVisitor AnnotateVis;
5641 SourceManager &SrcMgr;
5642 bool HasContextSensitiveKeywords;
5643
5644 struct PostChildrenInfo {
5645 CXCursor Cursor;
5646 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005647 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005648 unsigned BeforeChildrenTokenIdx;
5649 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005650 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005651
5652 CXToken &getTok(unsigned Idx) {
5653 assert(Idx < NumTokens);
5654 return Tokens[Idx];
5655 }
5656 const CXToken &getTok(unsigned Idx) const {
5657 assert(Idx < NumTokens);
5658 return Tokens[Idx];
5659 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005660 bool MoreTokens() const { return TokIdx < NumTokens; }
5661 unsigned NextToken() const { return TokIdx; }
5662 void AdvanceToken() { ++TokIdx; }
5663 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005664 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005665 }
5666 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005667 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005668 }
5669 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005670 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005671 }
5672
5673 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005674 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005675 SourceRange);
5676
5677public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005678 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005679 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005680 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005681 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005682 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005683 AnnotateTokensVisitor, this,
5684 /*VisitPreprocessorLast=*/true,
5685 /*VisitIncludedEntities=*/false,
5686 RegionOfInterest,
5687 /*VisitDeclsOnly=*/false,
5688 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005689 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005690 HasContextSensitiveKeywords(false) { }
5691
5692 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5693 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5694 bool postVisitChildren(CXCursor cursor);
5695 void AnnotateTokens();
5696
5697 /// \brief Determine whether the annotator saw any cursors that have
5698 /// context-sensitive keywords.
5699 bool hasContextSensitiveKeywords() const {
5700 return HasContextSensitiveKeywords;
5701 }
5702
5703 ~AnnotateTokensWorker() {
5704 assert(PostChildrenInfos.empty());
5705 }
5706};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00005707}
Guy Benyei11169dd2012-12-18 14:30:41 +00005708
5709void AnnotateTokensWorker::AnnotateTokens() {
5710 // Walk the AST within the region of interest, annotating tokens
5711 // along the way.
5712 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005713}
Guy Benyei11169dd2012-12-18 14:30:41 +00005714
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005715static inline void updateCursorAnnotation(CXCursor &Cursor,
5716 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005717 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005718 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005719 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005720}
5721
5722/// \brief It annotates and advances tokens with a cursor until the comparison
5723//// between the cursor location and the source range is the same as
5724/// \arg compResult.
5725///
5726/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5727/// Pass RangeOverlap to annotate tokens inside a range.
5728void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5729 RangeComparisonResult compResult,
5730 SourceRange range) {
5731 while (MoreTokens()) {
5732 const unsigned I = NextToken();
5733 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005734 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5735 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005736
5737 SourceLocation TokLoc = GetTokenLoc(I);
5738 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005739 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005740 AdvanceToken();
5741 continue;
5742 }
5743 break;
5744 }
5745}
5746
5747/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005748/// \returns true if it advanced beyond all macro tokens, false otherwise.
5749bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005750 CXCursor updateC,
5751 RangeComparisonResult compResult,
5752 SourceRange range) {
5753 assert(MoreTokens());
5754 assert(isFunctionMacroToken(NextToken()) &&
5755 "Should be called only for macro arg tokens");
5756
5757 // This works differently than annotateAndAdvanceTokens; because expanded
5758 // macro arguments can have arbitrary translation-unit source order, we do not
5759 // advance the token index one by one until a token fails the range test.
5760 // We only advance once past all of the macro arg tokens if all of them
5761 // pass the range test. If one of them fails we keep the token index pointing
5762 // at the start of the macro arg tokens so that the failing token will be
5763 // annotated by a subsequent annotation try.
5764
5765 bool atLeastOneCompFail = false;
5766
5767 unsigned I = NextToken();
5768 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5769 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5770 if (TokLoc.isFileID())
5771 continue; // not macro arg token, it's parens or comma.
5772 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5773 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5774 Cursors[I] = updateC;
5775 } else
5776 atLeastOneCompFail = true;
5777 }
5778
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005779 if (atLeastOneCompFail)
5780 return false;
5781
5782 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5783 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005784}
5785
5786enum CXChildVisitResult
5787AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005788 SourceRange cursorRange = getRawCursorExtent(cursor);
5789 if (cursorRange.isInvalid())
5790 return CXChildVisit_Recurse;
5791
5792 if (!HasContextSensitiveKeywords) {
5793 // Objective-C properties can have context-sensitive keywords.
5794 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005795 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005796 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5797 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5798 }
5799 // Objective-C methods can have context-sensitive keywords.
5800 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5801 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005802 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005803 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5804 if (Method->getObjCDeclQualifier())
5805 HasContextSensitiveKeywords = true;
5806 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005807 for (const auto *P : Method->params()) {
5808 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005809 HasContextSensitiveKeywords = true;
5810 break;
5811 }
5812 }
5813 }
5814 }
5815 }
5816 // C++ methods can have context-sensitive keywords.
5817 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005818 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005819 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5820 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5821 HasContextSensitiveKeywords = true;
5822 }
5823 }
5824 // C++ classes can have context-sensitive keywords.
5825 else if (cursor.kind == CXCursor_StructDecl ||
5826 cursor.kind == CXCursor_ClassDecl ||
5827 cursor.kind == CXCursor_ClassTemplate ||
5828 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005829 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005830 if (D->hasAttr<FinalAttr>())
5831 HasContextSensitiveKeywords = true;
5832 }
5833 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005834
5835 // Don't override a property annotation with its getter/setter method.
5836 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5837 parent.kind == CXCursor_ObjCPropertyDecl)
5838 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005839
5840 if (clang_isPreprocessing(cursor.kind)) {
5841 // Items in the preprocessing record are kept separate from items in
5842 // declarations, so we keep a separate token index.
5843 unsigned SavedTokIdx = TokIdx;
5844 TokIdx = PreprocessingTokIdx;
5845
5846 // Skip tokens up until we catch up to the beginning of the preprocessing
5847 // entry.
5848 while (MoreTokens()) {
5849 const unsigned I = NextToken();
5850 SourceLocation TokLoc = GetTokenLoc(I);
5851 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5852 case RangeBefore:
5853 AdvanceToken();
5854 continue;
5855 case RangeAfter:
5856 case RangeOverlap:
5857 break;
5858 }
5859 break;
5860 }
5861
5862 // Look at all of the tokens within this range.
5863 while (MoreTokens()) {
5864 const unsigned I = NextToken();
5865 SourceLocation TokLoc = GetTokenLoc(I);
5866 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5867 case RangeBefore:
5868 llvm_unreachable("Infeasible");
5869 case RangeAfter:
5870 break;
5871 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005872 // For macro expansions, just note where the beginning of the macro
5873 // expansion occurs.
5874 if (cursor.kind == CXCursor_MacroExpansion) {
5875 if (TokLoc == cursorRange.getBegin())
5876 Cursors[I] = cursor;
5877 AdvanceToken();
5878 break;
5879 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005880 // We may have already annotated macro names inside macro definitions.
5881 if (Cursors[I].kind != CXCursor_MacroExpansion)
5882 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005883 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005884 continue;
5885 }
5886 break;
5887 }
5888
5889 // Save the preprocessing token index; restore the non-preprocessing
5890 // token index.
5891 PreprocessingTokIdx = TokIdx;
5892 TokIdx = SavedTokIdx;
5893 return CXChildVisit_Recurse;
5894 }
5895
5896 if (cursorRange.isInvalid())
5897 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005898
5899 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005900 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005901 const enum CXCursorKind K = clang_getCursorKind(parent);
5902 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005903 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5904 // Attributes are annotated out-of-order, skip tokens until we reach it.
5905 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005906 ? clang_getNullCursor() : parent;
5907
5908 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5909
5910 // Avoid having the cursor of an expression "overwrite" the annotation of the
5911 // variable declaration that it belongs to.
5912 // This can happen for C++ constructor expressions whose range generally
5913 // include the variable declaration, e.g.:
5914 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005915 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005916 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005917 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005918 const unsigned I = NextToken();
5919 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5920 E->getLocStart() == D->getLocation() &&
5921 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005922 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005923 AdvanceToken();
5924 }
5925 }
5926 }
5927
5928 // Before recursing into the children keep some state that we are going
5929 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5930 // extra work after the child nodes are visited.
5931 // Note that we don't call VisitChildren here to avoid traversing statements
5932 // code-recursively which can blow the stack.
5933
5934 PostChildrenInfo Info;
5935 Info.Cursor = cursor;
5936 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005937 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005938 Info.BeforeChildrenTokenIdx = NextToken();
5939 PostChildrenInfos.push_back(Info);
5940
5941 return CXChildVisit_Recurse;
5942}
5943
5944bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5945 if (PostChildrenInfos.empty())
5946 return false;
5947 const PostChildrenInfo &Info = PostChildrenInfos.back();
5948 if (!clang_equalCursors(Info.Cursor, cursor))
5949 return false;
5950
5951 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5952 const unsigned AfterChildren = NextToken();
5953 SourceRange cursorRange = Info.CursorRange;
5954
5955 // Scan the tokens that are at the end of the cursor, but are not captured
5956 // but the child cursors.
5957 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5958
5959 // Scan the tokens that are at the beginning of the cursor, but are not
5960 // capture by the child cursors.
5961 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5962 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5963 break;
5964
5965 Cursors[I] = cursor;
5966 }
5967
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005968 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5969 // encountered the attribute cursor.
5970 if (clang_isAttribute(cursor.kind))
5971 TokIdx = Info.BeforeReachingCursorIdx;
5972
Guy Benyei11169dd2012-12-18 14:30:41 +00005973 PostChildrenInfos.pop_back();
5974 return false;
5975}
5976
5977static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5978 CXCursor parent,
5979 CXClientData client_data) {
5980 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5981}
5982
5983static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5984 CXClientData client_data) {
5985 return static_cast<AnnotateTokensWorker*>(client_data)->
5986 postVisitChildren(cursor);
5987}
5988
5989namespace {
5990
5991/// \brief Uses the macro expansions in the preprocessing record to find
5992/// and mark tokens that are macro arguments. This info is used by the
5993/// AnnotateTokensWorker.
5994class MarkMacroArgTokensVisitor {
5995 SourceManager &SM;
5996 CXToken *Tokens;
5997 unsigned NumTokens;
5998 unsigned CurIdx;
5999
6000public:
6001 MarkMacroArgTokensVisitor(SourceManager &SM,
6002 CXToken *tokens, unsigned numTokens)
6003 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
6004
6005 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
6006 if (cursor.kind != CXCursor_MacroExpansion)
6007 return CXChildVisit_Continue;
6008
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006009 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00006010 if (macroRange.getBegin() == macroRange.getEnd())
6011 return CXChildVisit_Continue; // it's not a function macro.
6012
6013 for (; CurIdx < NumTokens; ++CurIdx) {
6014 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
6015 macroRange.getBegin()))
6016 break;
6017 }
6018
6019 if (CurIdx == NumTokens)
6020 return CXChildVisit_Break;
6021
6022 for (; CurIdx < NumTokens; ++CurIdx) {
6023 SourceLocation tokLoc = getTokenLoc(CurIdx);
6024 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
6025 break;
6026
6027 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
6028 }
6029
6030 if (CurIdx == NumTokens)
6031 return CXChildVisit_Break;
6032
6033 return CXChildVisit_Continue;
6034 }
6035
6036private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006037 CXToken &getTok(unsigned Idx) {
6038 assert(Idx < NumTokens);
6039 return Tokens[Idx];
6040 }
6041 const CXToken &getTok(unsigned Idx) const {
6042 assert(Idx < NumTokens);
6043 return Tokens[Idx];
6044 }
6045
Guy Benyei11169dd2012-12-18 14:30:41 +00006046 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006047 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006048 }
6049
6050 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
6051 // The third field is reserved and currently not used. Use it here
6052 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006053 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00006054 }
6055};
6056
6057} // end anonymous namespace
6058
6059static CXChildVisitResult
6060MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
6061 CXClientData client_data) {
6062 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
6063 parent);
6064}
6065
6066namespace {
6067 struct clang_annotateTokens_Data {
6068 CXTranslationUnit TU;
6069 ASTUnit *CXXUnit;
6070 CXToken *Tokens;
6071 unsigned NumTokens;
6072 CXCursor *Cursors;
6073 };
6074}
6075
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006076/// \brief Used by \c annotatePreprocessorTokens.
6077/// \returns true if lexing was finished, false otherwise.
6078static bool lexNext(Lexer &Lex, Token &Tok,
6079 unsigned &NextIdx, unsigned NumTokens) {
6080 if (NextIdx >= NumTokens)
6081 return true;
6082
6083 ++NextIdx;
6084 Lex.LexFromRawLexer(Tok);
6085 if (Tok.is(tok::eof))
6086 return true;
6087
6088 return false;
6089}
6090
Guy Benyei11169dd2012-12-18 14:30:41 +00006091static void annotatePreprocessorTokens(CXTranslationUnit TU,
6092 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006093 CXCursor *Cursors,
6094 CXToken *Tokens,
6095 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006096 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006097
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006098 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00006099 SourceManager &SourceMgr = CXXUnit->getSourceManager();
6100 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006101 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00006102 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006103 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00006104
6105 if (BeginLocInfo.first != EndLocInfo.first)
6106 return;
6107
6108 StringRef Buffer;
6109 bool Invalid = false;
6110 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
6111 if (Buffer.empty() || Invalid)
6112 return;
6113
6114 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
6115 CXXUnit->getASTContext().getLangOpts(),
6116 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
6117 Buffer.end());
6118 Lex.SetCommentRetentionState(true);
6119
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006120 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006121 // Lex tokens in raw mode until we hit the end of the range, to avoid
6122 // entering #includes or expanding macros.
6123 while (true) {
6124 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006125 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6126 break;
6127 unsigned TokIdx = NextIdx-1;
6128 assert(Tok.getLocation() ==
6129 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006130
6131 reprocess:
6132 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006133 // We have found a preprocessing directive. Annotate the tokens
6134 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00006135 //
6136 // FIXME: Some simple tests here could identify macro definitions and
6137 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006138
6139 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006140 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6141 break;
6142
Craig Topper69186e72014-06-08 08:38:04 +00006143 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00006144 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006145 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6146 break;
6147
6148 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00006149 IdentifierInfo &II =
6150 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006151 SourceLocation MappedTokLoc =
6152 CXXUnit->mapLocationToPreamble(Tok.getLocation());
6153 MI = getMacroInfo(II, MappedTokLoc, TU);
6154 }
6155 }
6156
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006157 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00006158 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006159 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
6160 finished = true;
6161 break;
6162 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006163 // If we are in a macro definition, check if the token was ever a
6164 // macro name and annotate it if that's the case.
6165 if (MI) {
6166 SourceLocation SaveLoc = Tok.getLocation();
6167 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
Richard Smith66a81862015-05-04 02:25:31 +00006168 MacroDefinitionRecord *MacroDef =
6169 checkForMacroInMacroDefinition(MI, Tok, TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006170 Tok.setLocation(SaveLoc);
6171 if (MacroDef)
Richard Smith66a81862015-05-04 02:25:31 +00006172 Cursors[NextIdx - 1] =
6173 MakeMacroExpansionCursor(MacroDef, Tok.getLocation(), TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006174 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006175 } while (!Tok.isAtStartOfLine());
6176
6177 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
6178 assert(TokIdx <= LastIdx);
6179 SourceLocation EndLoc =
6180 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
6181 CXCursor Cursor =
6182 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
6183
6184 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006185 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006186
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006187 if (finished)
6188 break;
6189 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00006190 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006191 }
6192}
6193
6194// This gets run a separate thread to avoid stack blowout.
6195static void clang_annotateTokensImpl(void *UserData) {
6196 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
6197 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
6198 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
6199 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
6200 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
6201
Dmitri Gribenko183436e2013-01-26 21:49:50 +00006202 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006203 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
6204 setThreadBackgroundPriority();
6205
6206 // Determine the region of interest, which contains all of the tokens.
6207 SourceRange RegionOfInterest;
6208 RegionOfInterest.setBegin(
6209 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
6210 RegionOfInterest.setEnd(
6211 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
6212 Tokens[NumTokens-1])));
6213
Guy Benyei11169dd2012-12-18 14:30:41 +00006214 // Relex the tokens within the source range to look for preprocessing
6215 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006216 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006217
6218 // If begin location points inside a macro argument, set it to the expansion
6219 // location so we can have the full context when annotating semantically.
6220 {
6221 SourceManager &SM = CXXUnit->getSourceManager();
6222 SourceLocation Loc =
6223 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
6224 if (Loc.isMacroID())
6225 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
6226 }
6227
Guy Benyei11169dd2012-12-18 14:30:41 +00006228 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
6229 // Search and mark tokens that are macro argument expansions.
6230 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
6231 Tokens, NumTokens);
6232 CursorVisitor MacroArgMarker(TU,
6233 MarkMacroArgTokensVisitorDelegate, &Visitor,
6234 /*VisitPreprocessorLast=*/true,
6235 /*VisitIncludedEntities=*/false,
6236 RegionOfInterest);
6237 MacroArgMarker.visitPreprocessedEntitiesInRegion();
6238 }
6239
6240 // Annotate all of the source locations in the region of interest that map to
6241 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006242 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00006243
6244 // FIXME: We use a ridiculous stack size here because the data-recursion
6245 // algorithm uses a large stack frame than the non-data recursive version,
6246 // and AnnotationTokensWorker currently transforms the data-recursion
6247 // algorithm back into a traditional recursion by explicitly calling
6248 // VisitChildren(). We will need to remove this explicit recursive call.
6249 W.AnnotateTokens();
6250
6251 // If we ran into any entities that involve context-sensitive keywords,
6252 // take another pass through the tokens to mark them as such.
6253 if (W.hasContextSensitiveKeywords()) {
6254 for (unsigned I = 0; I != NumTokens; ++I) {
6255 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
6256 continue;
6257
6258 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
6259 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006260 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006261 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
6262 if (Property->getPropertyAttributesAsWritten() != 0 &&
6263 llvm::StringSwitch<bool>(II->getName())
6264 .Case("readonly", true)
6265 .Case("assign", true)
6266 .Case("unsafe_unretained", true)
6267 .Case("readwrite", true)
6268 .Case("retain", true)
6269 .Case("copy", true)
6270 .Case("nonatomic", true)
6271 .Case("atomic", true)
6272 .Case("getter", true)
6273 .Case("setter", true)
6274 .Case("strong", true)
6275 .Case("weak", true)
6276 .Default(false))
6277 Tokens[I].int_data[0] = CXToken_Keyword;
6278 }
6279 continue;
6280 }
6281
6282 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6283 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6284 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6285 if (llvm::StringSwitch<bool>(II->getName())
6286 .Case("in", true)
6287 .Case("out", true)
6288 .Case("inout", true)
6289 .Case("oneway", true)
6290 .Case("bycopy", true)
6291 .Case("byref", true)
6292 .Default(false))
6293 Tokens[I].int_data[0] = CXToken_Keyword;
6294 continue;
6295 }
6296
6297 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6298 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6299 Tokens[I].int_data[0] = CXToken_Keyword;
6300 continue;
6301 }
6302 }
6303 }
6304}
6305
6306extern "C" {
6307
6308void clang_annotateTokens(CXTranslationUnit TU,
6309 CXToken *Tokens, unsigned NumTokens,
6310 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006311 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006312 LOG_BAD_TU(TU);
6313 return;
6314 }
6315 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006316 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006317 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006318 }
6319
6320 LOG_FUNC_SECTION {
6321 *Log << TU << ' ';
6322 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6323 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6324 *Log << clang_getRange(bloc, eloc);
6325 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006326
6327 // Any token we don't specifically annotate will have a NULL cursor.
6328 CXCursor C = clang_getNullCursor();
6329 for (unsigned I = 0; I != NumTokens; ++I)
6330 Cursors[I] = C;
6331
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006332 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006333 if (!CXXUnit)
6334 return;
6335
6336 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
6337
6338 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
6339 llvm::CrashRecoveryContext CRC;
6340 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
6341 GetSafetyThreadStackSize() * 2)) {
6342 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6343 }
6344}
6345
6346} // end: extern "C"
6347
6348//===----------------------------------------------------------------------===//
6349// Operations for querying linkage of a cursor.
6350//===----------------------------------------------------------------------===//
6351
6352extern "C" {
6353CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6354 if (!clang_isDeclaration(cursor.kind))
6355 return CXLinkage_Invalid;
6356
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006357 const Decl *D = cxcursor::getCursorDecl(cursor);
6358 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006359 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006360 case NoLinkage:
6361 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006362 case InternalLinkage: return CXLinkage_Internal;
6363 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6364 case ExternalLinkage: return CXLinkage_External;
6365 };
6366
6367 return CXLinkage_Invalid;
6368}
6369} // end: extern "C"
6370
6371//===----------------------------------------------------------------------===//
6372// Operations for querying language of a cursor.
6373//===----------------------------------------------------------------------===//
6374
6375static CXLanguageKind getDeclLanguage(const Decl *D) {
6376 if (!D)
6377 return CXLanguage_C;
6378
6379 switch (D->getKind()) {
6380 default:
6381 break;
6382 case Decl::ImplicitParam:
6383 case Decl::ObjCAtDefsField:
6384 case Decl::ObjCCategory:
6385 case Decl::ObjCCategoryImpl:
6386 case Decl::ObjCCompatibleAlias:
6387 case Decl::ObjCImplementation:
6388 case Decl::ObjCInterface:
6389 case Decl::ObjCIvar:
6390 case Decl::ObjCMethod:
6391 case Decl::ObjCProperty:
6392 case Decl::ObjCPropertyImpl:
6393 case Decl::ObjCProtocol:
Douglas Gregor85f3f952015-07-07 03:57:15 +00006394 case Decl::ObjCTypeParam:
Guy Benyei11169dd2012-12-18 14:30:41 +00006395 return CXLanguage_ObjC;
6396 case Decl::CXXConstructor:
6397 case Decl::CXXConversion:
6398 case Decl::CXXDestructor:
6399 case Decl::CXXMethod:
6400 case Decl::CXXRecord:
6401 case Decl::ClassTemplate:
6402 case Decl::ClassTemplatePartialSpecialization:
6403 case Decl::ClassTemplateSpecialization:
6404 case Decl::Friend:
6405 case Decl::FriendTemplate:
6406 case Decl::FunctionTemplate:
6407 case Decl::LinkageSpec:
6408 case Decl::Namespace:
6409 case Decl::NamespaceAlias:
6410 case Decl::NonTypeTemplateParm:
6411 case Decl::StaticAssert:
6412 case Decl::TemplateTemplateParm:
6413 case Decl::TemplateTypeParm:
6414 case Decl::UnresolvedUsingTypename:
6415 case Decl::UnresolvedUsingValue:
6416 case Decl::Using:
6417 case Decl::UsingDirective:
6418 case Decl::UsingShadow:
6419 return CXLanguage_CPlusPlus;
6420 }
6421
6422 return CXLanguage_C;
6423}
6424
6425extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006426
6427static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6428 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
6429 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00006430
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006431 switch (D->getAvailability()) {
6432 case AR_Available:
6433 case AR_NotYetIntroduced:
6434 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006435 return getCursorAvailabilityForDecl(
6436 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006437 return CXAvailability_Available;
6438
6439 case AR_Deprecated:
6440 return CXAvailability_Deprecated;
6441
6442 case AR_Unavailable:
6443 return CXAvailability_NotAvailable;
6444 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006445
6446 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006447}
6448
Guy Benyei11169dd2012-12-18 14:30:41 +00006449enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6450 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006451 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6452 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006453
6454 return CXAvailability_Available;
6455}
6456
6457static CXVersion convertVersion(VersionTuple In) {
6458 CXVersion Out = { -1, -1, -1 };
6459 if (In.empty())
6460 return Out;
6461
6462 Out.Major = In.getMajor();
6463
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006464 Optional<unsigned> Minor = In.getMinor();
6465 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006466 Out.Minor = *Minor;
6467 else
6468 return Out;
6469
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006470 Optional<unsigned> Subminor = In.getSubminor();
6471 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006472 Out.Subminor = *Subminor;
6473
6474 return Out;
6475}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006476
6477static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6478 int *always_deprecated,
6479 CXString *deprecated_message,
6480 int *always_unavailable,
6481 CXString *unavailable_message,
6482 CXPlatformAvailability *availability,
6483 int availability_size) {
6484 bool HadAvailAttr = false;
6485 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006486 for (auto A : D->attrs()) {
6487 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006488 HadAvailAttr = true;
6489 if (always_deprecated)
6490 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006491 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006492 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006493 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006494 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006495 continue;
6496 }
6497
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006498 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006499 HadAvailAttr = true;
6500 if (always_unavailable)
6501 *always_unavailable = 1;
6502 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006503 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006504 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6505 }
6506 continue;
6507 }
6508
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006509 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006510 HadAvailAttr = true;
6511 if (N < availability_size) {
6512 availability[N].Platform
6513 = cxstring::createDup(Avail->getPlatform()->getName());
6514 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6515 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6516 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6517 availability[N].Unavailable = Avail->getUnavailable();
6518 availability[N].Message = cxstring::createDup(Avail->getMessage());
6519 }
6520 ++N;
6521 }
6522 }
6523
6524 if (!HadAvailAttr)
6525 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6526 return getCursorPlatformAvailabilityForDecl(
6527 cast<Decl>(EnumConst->getDeclContext()),
6528 always_deprecated,
6529 deprecated_message,
6530 always_unavailable,
6531 unavailable_message,
6532 availability,
6533 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006534
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006535 return N;
6536}
6537
Guy Benyei11169dd2012-12-18 14:30:41 +00006538int clang_getCursorPlatformAvailability(CXCursor cursor,
6539 int *always_deprecated,
6540 CXString *deprecated_message,
6541 int *always_unavailable,
6542 CXString *unavailable_message,
6543 CXPlatformAvailability *availability,
6544 int availability_size) {
6545 if (always_deprecated)
6546 *always_deprecated = 0;
6547 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006548 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006549 if (always_unavailable)
6550 *always_unavailable = 0;
6551 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006552 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006553
Guy Benyei11169dd2012-12-18 14:30:41 +00006554 if (!clang_isDeclaration(cursor.kind))
6555 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006556
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006557 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006558 if (!D)
6559 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006560
6561 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6562 deprecated_message,
6563 always_unavailable,
6564 unavailable_message,
6565 availability,
6566 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006567}
6568
6569void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6570 clang_disposeString(availability->Platform);
6571 clang_disposeString(availability->Message);
6572}
6573
6574CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6575 if (clang_isDeclaration(cursor.kind))
6576 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6577
6578 return CXLanguage_Invalid;
6579}
6580
6581 /// \brief If the given cursor is the "templated" declaration
6582 /// descibing a class or function template, return the class or
6583 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006584static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006585 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006586 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006587
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006588 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006589 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6590 return FunTmpl;
6591
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006592 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006593 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6594 return ClassTmpl;
6595
6596 return D;
6597}
6598
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006599
6600enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
6601 StorageClass sc = SC_None;
6602 const Decl *D = getCursorDecl(C);
6603 if (D) {
6604 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
6605 sc = FD->getStorageClass();
6606 } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
6607 sc = VD->getStorageClass();
6608 } else {
6609 return CX_SC_Invalid;
6610 }
6611 } else {
6612 return CX_SC_Invalid;
6613 }
6614 switch (sc) {
6615 case SC_None:
6616 return CX_SC_None;
6617 case SC_Extern:
6618 return CX_SC_Extern;
6619 case SC_Static:
6620 return CX_SC_Static;
6621 case SC_PrivateExtern:
6622 return CX_SC_PrivateExtern;
6623 case SC_OpenCLWorkGroupLocal:
6624 return CX_SC_OpenCLWorkGroupLocal;
6625 case SC_Auto:
6626 return CX_SC_Auto;
6627 case SC_Register:
6628 return CX_SC_Register;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006629 }
Kaelyn Takataab61e702014-10-15 18:03:26 +00006630 llvm_unreachable("Unhandled storage class!");
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006631}
6632
Guy Benyei11169dd2012-12-18 14:30:41 +00006633CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6634 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006635 if (const Decl *D = getCursorDecl(cursor)) {
6636 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006637 if (!DC)
6638 return clang_getNullCursor();
6639
6640 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6641 getCursorTU(cursor));
6642 }
6643 }
6644
6645 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006646 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006647 return MakeCXCursor(D, getCursorTU(cursor));
6648 }
6649
6650 return clang_getNullCursor();
6651}
6652
6653CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6654 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006655 if (const Decl *D = getCursorDecl(cursor)) {
6656 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006657 if (!DC)
6658 return clang_getNullCursor();
6659
6660 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6661 getCursorTU(cursor));
6662 }
6663 }
6664
6665 // FIXME: Note that we can't easily compute the lexical context of a
6666 // statement or expression, so we return nothing.
6667 return clang_getNullCursor();
6668}
6669
6670CXFile clang_getIncludedFile(CXCursor cursor) {
6671 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006672 return nullptr;
6673
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006674 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006675 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006676}
6677
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006678unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6679 if (C.kind != CXCursor_ObjCPropertyDecl)
6680 return CXObjCPropertyAttr_noattr;
6681
6682 unsigned Result = CXObjCPropertyAttr_noattr;
6683 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6684 ObjCPropertyDecl::PropertyAttributeKind Attr =
6685 PD->getPropertyAttributesAsWritten();
6686
6687#define SET_CXOBJCPROP_ATTR(A) \
6688 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6689 Result |= CXObjCPropertyAttr_##A
6690 SET_CXOBJCPROP_ATTR(readonly);
6691 SET_CXOBJCPROP_ATTR(getter);
6692 SET_CXOBJCPROP_ATTR(assign);
6693 SET_CXOBJCPROP_ATTR(readwrite);
6694 SET_CXOBJCPROP_ATTR(retain);
6695 SET_CXOBJCPROP_ATTR(copy);
6696 SET_CXOBJCPROP_ATTR(nonatomic);
6697 SET_CXOBJCPROP_ATTR(setter);
6698 SET_CXOBJCPROP_ATTR(atomic);
6699 SET_CXOBJCPROP_ATTR(weak);
6700 SET_CXOBJCPROP_ATTR(strong);
6701 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6702#undef SET_CXOBJCPROP_ATTR
6703
6704 return Result;
6705}
6706
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006707unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6708 if (!clang_isDeclaration(C.kind))
6709 return CXObjCDeclQualifier_None;
6710
6711 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6712 const Decl *D = getCursorDecl(C);
6713 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6714 QT = MD->getObjCDeclQualifier();
6715 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6716 QT = PD->getObjCDeclQualifier();
6717 if (QT == Decl::OBJC_TQ_None)
6718 return CXObjCDeclQualifier_None;
6719
6720 unsigned Result = CXObjCDeclQualifier_None;
6721 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6722 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6723 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6724 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6725 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6726 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6727
6728 return Result;
6729}
6730
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006731unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6732 if (!clang_isDeclaration(C.kind))
6733 return 0;
6734
6735 const Decl *D = getCursorDecl(C);
6736 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6737 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6738 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6739 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6740
6741 return 0;
6742}
6743
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006744unsigned clang_Cursor_isVariadic(CXCursor C) {
6745 if (!clang_isDeclaration(C.kind))
6746 return 0;
6747
6748 const Decl *D = getCursorDecl(C);
6749 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6750 return FD->isVariadic();
6751 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6752 return MD->isVariadic();
6753
6754 return 0;
6755}
6756
Guy Benyei11169dd2012-12-18 14:30:41 +00006757CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6758 if (!clang_isDeclaration(C.kind))
6759 return clang_getNullRange();
6760
6761 const Decl *D = getCursorDecl(C);
6762 ASTContext &Context = getCursorContext(C);
6763 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6764 if (!RC)
6765 return clang_getNullRange();
6766
6767 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6768}
6769
6770CXString clang_Cursor_getRawCommentText(CXCursor C) {
6771 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006772 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006773
6774 const Decl *D = getCursorDecl(C);
6775 ASTContext &Context = getCursorContext(C);
6776 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6777 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6778 StringRef();
6779
6780 // Don't duplicate the string because RawText points directly into source
6781 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006782 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006783}
6784
6785CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6786 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006787 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006788
6789 const Decl *D = getCursorDecl(C);
6790 const ASTContext &Context = getCursorContext(C);
6791 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6792
6793 if (RC) {
6794 StringRef BriefText = RC->getBriefText(Context);
6795
6796 // Don't duplicate the string because RawComment ensures that this memory
6797 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006798 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006799 }
6800
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006801 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006802}
6803
Guy Benyei11169dd2012-12-18 14:30:41 +00006804CXModule clang_Cursor_getModule(CXCursor C) {
6805 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006806 if (const ImportDecl *ImportD =
6807 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006808 return ImportD->getImportedModule();
6809 }
6810
Craig Topper69186e72014-06-08 08:38:04 +00006811 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006812}
6813
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006814CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6815 if (isNotUsableTU(TU)) {
6816 LOG_BAD_TU(TU);
6817 return nullptr;
6818 }
6819 if (!File)
6820 return nullptr;
6821 FileEntry *FE = static_cast<FileEntry *>(File);
6822
6823 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6824 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6825 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6826
Richard Smithfeb54b62014-10-23 02:01:19 +00006827 return Header.getModule();
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006828}
6829
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006830CXFile clang_Module_getASTFile(CXModule CXMod) {
6831 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006832 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006833 Module *Mod = static_cast<Module*>(CXMod);
6834 return const_cast<FileEntry *>(Mod->getASTFile());
6835}
6836
Guy Benyei11169dd2012-12-18 14:30:41 +00006837CXModule clang_Module_getParent(CXModule CXMod) {
6838 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006839 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006840 Module *Mod = static_cast<Module*>(CXMod);
6841 return Mod->Parent;
6842}
6843
6844CXString clang_Module_getName(CXModule CXMod) {
6845 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006846 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006847 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006848 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006849}
6850
6851CXString clang_Module_getFullName(CXModule CXMod) {
6852 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006853 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006854 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006855 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006856}
6857
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006858int clang_Module_isSystem(CXModule CXMod) {
6859 if (!CXMod)
6860 return 0;
6861 Module *Mod = static_cast<Module*>(CXMod);
6862 return Mod->IsSystem;
6863}
6864
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006865unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6866 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006867 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006868 LOG_BAD_TU(TU);
6869 return 0;
6870 }
6871 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006872 return 0;
6873 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006874 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6875 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6876 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006877}
6878
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006879CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6880 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006881 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006882 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006883 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006884 }
6885 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006886 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006887 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006888 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006889
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006890 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6891 if (Index < TopHeaders.size())
6892 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006893
Craig Topper69186e72014-06-08 08:38:04 +00006894 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006895}
6896
6897} // end: extern "C"
6898
6899//===----------------------------------------------------------------------===//
6900// C++ AST instrospection.
6901//===----------------------------------------------------------------------===//
6902
6903extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006904unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6905 if (!clang_isDeclaration(C.kind))
6906 return 0;
6907
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006908 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006909 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006910 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006911 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6912}
6913
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006914unsigned clang_CXXMethod_isConst(CXCursor C) {
6915 if (!clang_isDeclaration(C.kind))
6916 return 0;
6917
6918 const Decl *D = cxcursor::getCursorDecl(C);
6919 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006920 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006921 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6922}
6923
Guy Benyei11169dd2012-12-18 14:30:41 +00006924unsigned clang_CXXMethod_isStatic(CXCursor C) {
6925 if (!clang_isDeclaration(C.kind))
6926 return 0;
6927
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006928 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006929 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006930 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006931 return (Method && Method->isStatic()) ? 1 : 0;
6932}
6933
6934unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6935 if (!clang_isDeclaration(C.kind))
6936 return 0;
6937
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006938 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006939 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006940 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006941 return (Method && Method->isVirtual()) ? 1 : 0;
6942}
6943} // end: extern "C"
6944
6945//===----------------------------------------------------------------------===//
6946// Attribute introspection.
6947//===----------------------------------------------------------------------===//
6948
6949extern "C" {
6950CXType clang_getIBOutletCollectionType(CXCursor C) {
6951 if (C.kind != CXCursor_IBOutletCollectionAttr)
6952 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6953
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006954 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006955 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6956
6957 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6958}
6959} // end: extern "C"
6960
6961//===----------------------------------------------------------------------===//
6962// Inspecting memory usage.
6963//===----------------------------------------------------------------------===//
6964
6965typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6966
6967static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6968 enum CXTUResourceUsageKind k,
6969 unsigned long amount) {
6970 CXTUResourceUsageEntry entry = { k, amount };
6971 entries.push_back(entry);
6972}
6973
6974extern "C" {
6975
6976const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6977 const char *str = "";
6978 switch (kind) {
6979 case CXTUResourceUsage_AST:
6980 str = "ASTContext: expressions, declarations, and types";
6981 break;
6982 case CXTUResourceUsage_Identifiers:
6983 str = "ASTContext: identifiers";
6984 break;
6985 case CXTUResourceUsage_Selectors:
6986 str = "ASTContext: selectors";
6987 break;
6988 case CXTUResourceUsage_GlobalCompletionResults:
6989 str = "Code completion: cached global results";
6990 break;
6991 case CXTUResourceUsage_SourceManagerContentCache:
6992 str = "SourceManager: content cache allocator";
6993 break;
6994 case CXTUResourceUsage_AST_SideTables:
6995 str = "ASTContext: side tables";
6996 break;
6997 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6998 str = "SourceManager: malloc'ed memory buffers";
6999 break;
7000 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
7001 str = "SourceManager: mmap'ed memory buffers";
7002 break;
7003 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
7004 str = "ExternalASTSource: malloc'ed memory buffers";
7005 break;
7006 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
7007 str = "ExternalASTSource: mmap'ed memory buffers";
7008 break;
7009 case CXTUResourceUsage_Preprocessor:
7010 str = "Preprocessor: malloc'ed memory";
7011 break;
7012 case CXTUResourceUsage_PreprocessingRecord:
7013 str = "Preprocessor: PreprocessingRecord";
7014 break;
7015 case CXTUResourceUsage_SourceManager_DataStructures:
7016 str = "SourceManager: data structures and tables";
7017 break;
7018 case CXTUResourceUsage_Preprocessor_HeaderSearch:
7019 str = "Preprocessor: header search tables";
7020 break;
7021 }
7022 return str;
7023}
7024
7025CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007026 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007027 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00007028 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00007029 return usage;
7030 }
7031
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007032 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00007033 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00007034 ASTContext &astContext = astUnit->getASTContext();
7035
7036 // How much memory is used by AST nodes and types?
7037 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
7038 (unsigned long) astContext.getASTAllocatedMemory());
7039
7040 // How much memory is used by identifiers?
7041 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
7042 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
7043
7044 // How much memory is used for selectors?
7045 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
7046 (unsigned long) astContext.Selectors.getTotalMemory());
7047
7048 // How much memory is used by ASTContext's side tables?
7049 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
7050 (unsigned long) astContext.getSideTableAllocatedMemory());
7051
7052 // How much memory is used for caching global code completion results?
7053 unsigned long completionBytes = 0;
7054 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00007055 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007056 completionBytes = completionAllocator->getTotalMemory();
7057 }
7058 createCXTUResourceUsageEntry(*entries,
7059 CXTUResourceUsage_GlobalCompletionResults,
7060 completionBytes);
7061
7062 // How much memory is being used by SourceManager's content cache?
7063 createCXTUResourceUsageEntry(*entries,
7064 CXTUResourceUsage_SourceManagerContentCache,
7065 (unsigned long) astContext.getSourceManager().getContentCacheSize());
7066
7067 // How much memory is being used by the MemoryBuffer's in SourceManager?
7068 const SourceManager::MemoryBufferSizes &srcBufs =
7069 astUnit->getSourceManager().getMemoryBufferSizes();
7070
7071 createCXTUResourceUsageEntry(*entries,
7072 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
7073 (unsigned long) srcBufs.malloc_bytes);
7074 createCXTUResourceUsageEntry(*entries,
7075 CXTUResourceUsage_SourceManager_Membuffer_MMap,
7076 (unsigned long) srcBufs.mmap_bytes);
7077 createCXTUResourceUsageEntry(*entries,
7078 CXTUResourceUsage_SourceManager_DataStructures,
7079 (unsigned long) astContext.getSourceManager()
7080 .getDataStructureSizes());
7081
7082 // How much memory is being used by the ExternalASTSource?
7083 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
7084 const ExternalASTSource::MemoryBufferSizes &sizes =
7085 esrc->getMemoryBufferSizes();
7086
7087 createCXTUResourceUsageEntry(*entries,
7088 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
7089 (unsigned long) sizes.malloc_bytes);
7090 createCXTUResourceUsageEntry(*entries,
7091 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
7092 (unsigned long) sizes.mmap_bytes);
7093 }
7094
7095 // How much memory is being used by the Preprocessor?
7096 Preprocessor &pp = astUnit->getPreprocessor();
7097 createCXTUResourceUsageEntry(*entries,
7098 CXTUResourceUsage_Preprocessor,
7099 pp.getTotalMemory());
7100
7101 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
7102 createCXTUResourceUsageEntry(*entries,
7103 CXTUResourceUsage_PreprocessingRecord,
7104 pRec->getTotalMemory());
7105 }
7106
7107 createCXTUResourceUsageEntry(*entries,
7108 CXTUResourceUsage_Preprocessor_HeaderSearch,
7109 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00007110
Guy Benyei11169dd2012-12-18 14:30:41 +00007111 CXTUResourceUsage usage = { (void*) entries.get(),
7112 (unsigned) entries->size(),
Alexander Kornienko6ee521c2015-01-23 15:36:10 +00007113 !entries->empty() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00007114 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00007115 return usage;
7116}
7117
7118void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
7119 if (usage.data)
7120 delete (MemUsageEntries*) usage.data;
7121}
7122
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007123CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
7124 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007125 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00007126 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007127
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007128 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007129 LOG_BAD_TU(TU);
7130 return skipped;
7131 }
7132
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007133 if (!file)
7134 return skipped;
7135
7136 ASTUnit *astUnit = cxtu::getASTUnit(TU);
7137 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
7138 if (!ppRec)
7139 return skipped;
7140
7141 ASTContext &Ctx = astUnit->getASTContext();
7142 SourceManager &sm = Ctx.getSourceManager();
7143 FileEntry *fileEntry = static_cast<FileEntry *>(file);
7144 FileID wantedFileID = sm.translateFile(fileEntry);
7145
7146 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
7147 std::vector<SourceRange> wantedRanges;
7148 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
7149 i != ei; ++i) {
7150 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
7151 wantedRanges.push_back(*i);
7152 }
7153
7154 skipped->count = wantedRanges.size();
7155 skipped->ranges = new CXSourceRange[skipped->count];
7156 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
7157 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
7158
7159 return skipped;
7160}
7161
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007162void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
7163 if (ranges) {
7164 delete[] ranges->ranges;
7165 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007166 }
7167}
7168
Guy Benyei11169dd2012-12-18 14:30:41 +00007169} // end extern "C"
7170
7171void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
7172 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
7173 for (unsigned I = 0; I != Usage.numEntries; ++I)
7174 fprintf(stderr, " %s: %lu\n",
7175 clang_getTUResourceUsageName(Usage.entries[I].kind),
7176 Usage.entries[I].amount);
7177
7178 clang_disposeCXTUResourceUsage(Usage);
7179}
7180
7181//===----------------------------------------------------------------------===//
7182// Misc. utility functions.
7183//===----------------------------------------------------------------------===//
7184
7185/// Default to using an 8 MB stack size on "safety" threads.
7186static unsigned SafetyStackThreadSize = 8 << 20;
7187
7188namespace clang {
7189
7190bool RunSafely(llvm::CrashRecoveryContext &CRC,
7191 void (*Fn)(void*), void *UserData,
7192 unsigned Size) {
7193 if (!Size)
7194 Size = GetSafetyThreadStackSize();
7195 if (Size)
7196 return CRC.RunSafelyOnThread(Fn, UserData, Size);
7197 return CRC.RunSafely(Fn, UserData);
7198}
7199
7200unsigned GetSafetyThreadStackSize() {
7201 return SafetyStackThreadSize;
7202}
7203
7204void SetSafetyThreadStackSize(unsigned Value) {
7205 SafetyStackThreadSize = Value;
7206}
7207
Alexander Kornienkoab9db512015-06-22 23:07:51 +00007208}
Guy Benyei11169dd2012-12-18 14:30:41 +00007209
7210void clang::setThreadBackgroundPriority() {
7211 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
7212 return;
7213
Alp Toker1a86ad22014-07-06 06:24:00 +00007214#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00007215 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
7216#endif
7217}
7218
7219void cxindex::printDiagsToStderr(ASTUnit *Unit) {
7220 if (!Unit)
7221 return;
7222
7223 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
7224 DEnd = Unit->stored_diag_end();
7225 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00007226 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00007227 CXString Msg = clang_formatDiagnostic(&Diag,
7228 clang_defaultDiagnosticDisplayOptions());
7229 fprintf(stderr, "%s\n", clang_getCString(Msg));
7230 clang_disposeString(Msg);
7231 }
7232#ifdef LLVM_ON_WIN32
7233 // On Windows, force a flush, since there may be multiple copies of
7234 // stderr and stdout in the file system, all with different buffers
7235 // but writing to the same device.
7236 fflush(stderr);
7237#endif
7238}
7239
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007240MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
7241 SourceLocation MacroDefLoc,
7242 CXTranslationUnit TU){
7243 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007244 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007245 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007246 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007247
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007248 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007249 Preprocessor &PP = Unit->getPreprocessor();
Richard Smith20e883e2015-04-29 23:20:19 +00007250 MacroDirective *MD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007251 if (MD) {
7252 for (MacroDirective::DefInfo
7253 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
7254 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
7255 return Def.getMacroInfo();
7256 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007257 }
7258
Craig Topper69186e72014-06-08 08:38:04 +00007259 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007260}
7261
Richard Smith66a81862015-05-04 02:25:31 +00007262const MacroInfo *cxindex::getMacroInfo(const MacroDefinitionRecord *MacroDef,
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007263 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007264 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007265 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007266 const IdentifierInfo *II = MacroDef->getName();
7267 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00007268 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007269
7270 return getMacroInfo(*II, MacroDef->getLocation(), TU);
7271}
7272
Richard Smith66a81862015-05-04 02:25:31 +00007273MacroDefinitionRecord *
7274cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, const Token &Tok,
7275 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007276 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007277 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007278 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00007279 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007280
7281 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007282 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007283 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
7284 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007285 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007286
7287 // Check that the token is inside the definition and not its argument list.
7288 SourceManager &SM = Unit->getSourceManager();
7289 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00007290 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007291 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00007292 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007293
7294 Preprocessor &PP = Unit->getPreprocessor();
7295 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
7296 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00007297 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007298
Alp Toker2d57cea2014-05-17 04:53:25 +00007299 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007300 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007301 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007302
7303 // Check that the identifier is not one of the macro arguments.
7304 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00007305 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007306
Richard Smith20e883e2015-04-29 23:20:19 +00007307 MacroDirective *InnerMD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007308 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00007309 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007310
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007311 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007312}
7313
Richard Smith66a81862015-05-04 02:25:31 +00007314MacroDefinitionRecord *
7315cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, SourceLocation Loc,
7316 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007317 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007318 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007319
7320 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007321 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007322 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007323 Preprocessor &PP = Unit->getPreprocessor();
7324 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00007325 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007326 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7327 Token Tok;
7328 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00007329 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007330
7331 return checkForMacroInMacroDefinition(MI, Tok, TU);
7332}
7333
Guy Benyei11169dd2012-12-18 14:30:41 +00007334extern "C" {
7335
7336CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007337 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00007338}
7339
7340} // end: extern "C"
7341
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007342Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7343 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007344 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007345 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007346 if (Unit->isMainFileAST())
7347 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007348 return *this;
7349 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007350 } else {
7351 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007352 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007353 return *this;
7354}
7355
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007356Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7357 *this << FE->getName();
7358 return *this;
7359}
7360
7361Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7362 CXString cursorName = clang_getCursorDisplayName(cursor);
7363 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7364 clang_disposeString(cursorName);
7365 return *this;
7366}
7367
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007368Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7369 CXFile File;
7370 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007371 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007372 CXString FileName = clang_getFileName(File);
7373 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7374 clang_disposeString(FileName);
7375 return *this;
7376}
7377
7378Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7379 CXSourceLocation BLoc = clang_getRangeStart(range);
7380 CXSourceLocation ELoc = clang_getRangeEnd(range);
7381
7382 CXFile BFile;
7383 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007384 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007385
7386 CXFile EFile;
7387 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007388 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007389
7390 CXString BFileName = clang_getFileName(BFile);
7391 if (BFile == EFile) {
7392 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7393 BLine, BColumn, ELine, EColumn);
7394 } else {
7395 CXString EFileName = clang_getFileName(EFile);
7396 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7397 BLine, BColumn)
7398 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7399 ELine, EColumn);
7400 clang_disposeString(EFileName);
7401 }
7402 clang_disposeString(BFileName);
7403 return *this;
7404}
7405
7406Logger &cxindex::Logger::operator<<(CXString Str) {
7407 *this << clang_getCString(Str);
7408 return *this;
7409}
7410
7411Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7412 LogOS << Fmt;
7413 return *this;
7414}
7415
Chandler Carruth37ad2582014-06-27 15:14:39 +00007416static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7417
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007418cxindex::Logger::~Logger() {
7419 LogOS.flush();
7420
Chandler Carruth37ad2582014-06-27 15:14:39 +00007421 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007422
7423 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7424
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007425 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007426 OS << "[libclang:" << Name << ':';
7427
Alp Toker1a86ad22014-07-06 06:24:00 +00007428#ifdef USE_DARWIN_THREADS
7429 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007430 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7431 OS << tid << ':';
7432#endif
7433
7434 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7435 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
Yaron Keren09fb7c62015-03-10 07:33:23 +00007436 OS << Msg << '\n';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007437
7438 if (Trace) {
Zachary Turner1fe2a8d2015-03-05 19:15:09 +00007439 llvm::sys::PrintStackTrace(OS);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007440 OS << "--------------------------------------------------\n";
7441 }
7442}