blob: f6710a096e7177aff817789841ac79c8fd0d6558 [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
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00002991static CXErrorCode
2992clang_parseTranslationUnit_Impl(CXIndex CIdx, const char *source_filename,
2993 const char *const *command_line_args,
2994 int num_command_line_args,
2995 ArrayRef<CXUnsavedFile> unsaved_files,
2996 unsigned options, CXTranslationUnit *out_TU) {
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002997 // Set up the initial return values.
2998 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002999 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003000
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003001 // Check arguments.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003002 if (!CIdx || !out_TU)
3003 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003004
Guy Benyei11169dd2012-12-18 14:30:41 +00003005 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3006
3007 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3008 setThreadBackgroundPriority();
3009
3010 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
3011 // FIXME: Add a flag for modules.
3012 TranslationUnitKind TUKind
3013 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00003014 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00003015 = options & CXTranslationUnit_CacheCompletionResults;
3016 bool IncludeBriefCommentsInCodeCompletion
3017 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
3018 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
3019 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
3020
3021 // Configure the diagnostics.
3022 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00003023 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00003024
3025 // Recover resources if we crash before exiting this function.
3026 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
3027 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00003028 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00003029
Ahmed Charlesb8984322014-03-07 20:03:18 +00003030 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3031 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003032
3033 // Recover resources if we crash before exiting this function.
3034 llvm::CrashRecoveryContextCleanupRegistrar<
3035 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3036
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003037 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003038 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003039 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003040 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003041 }
3042
Ahmed Charlesb8984322014-03-07 20:03:18 +00003043 std::unique_ptr<std::vector<const char *>> Args(
3044 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003045
3046 // Recover resources if we crash before exiting this method.
3047 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
3048 ArgsCleanup(Args.get());
3049
3050 // Since the Clang C library is primarily used by batch tools dealing with
3051 // (often very broken) source code, where spell-checking can have a
3052 // significant negative impact on performance (particularly when
3053 // precompiled headers are involved), we disable it by default.
3054 // Only do this if we haven't found a spell-checking-related argument.
3055 bool FoundSpellCheckingArgument = false;
3056 for (int I = 0; I != num_command_line_args; ++I) {
3057 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
3058 strcmp(command_line_args[I], "-fspell-checking") == 0) {
3059 FoundSpellCheckingArgument = true;
3060 break;
3061 }
3062 }
3063 if (!FoundSpellCheckingArgument)
3064 Args->push_back("-fno-spell-checking");
3065
3066 Args->insert(Args->end(), command_line_args,
3067 command_line_args + num_command_line_args);
3068
3069 // The 'source_filename' argument is optional. If the caller does not
3070 // specify it then it is assumed that the source file is specified
3071 // in the actual argument list.
3072 // Put the source file after command_line_args otherwise if '-x' flag is
3073 // present it will be unused.
3074 if (source_filename)
3075 Args->push_back(source_filename);
3076
3077 // Do we need the detailed preprocessing record?
3078 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
3079 Args->push_back("-Xclang");
3080 Args->push_back("-detailed-preprocessing-record");
3081 }
3082
3083 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00003084 std::unique_ptr<ASTUnit> ErrUnit;
3085 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003086 Args->data(), Args->data() + Args->size(),
3087 CXXIdx->getPCHContainerOperations(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00003088 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
3089 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
3090 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
3091 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
3092 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
3093 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00003094
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003095 // Early failures in LoadFromCommandLine may return with ErrUnit unset.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003096 if (!Unit && !ErrUnit)
3097 return CXError_ASTReadError;
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003098
Guy Benyei11169dd2012-12-18 14:30:41 +00003099 if (NumErrors != Diags->getClient()->getNumErrors()) {
3100 // Make sure to check that 'Unit' is non-NULL.
3101 if (CXXIdx->getDisplayDiagnostics())
3102 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
3103 }
3104
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003105 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get()))
3106 return CXError_ASTReadError;
3107
3108 *out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
3109 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003110}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003111
3112CXTranslationUnit
3113clang_parseTranslationUnit(CXIndex CIdx,
3114 const char *source_filename,
3115 const char *const *command_line_args,
3116 int num_command_line_args,
3117 struct CXUnsavedFile *unsaved_files,
3118 unsigned num_unsaved_files,
3119 unsigned options) {
3120 CXTranslationUnit TU;
3121 enum CXErrorCode Result = clang_parseTranslationUnit2(
3122 CIdx, source_filename, command_line_args, num_command_line_args,
3123 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00003124 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003125 assert((TU && Result == CXError_Success) ||
3126 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003127 return TU;
3128}
3129
3130enum CXErrorCode clang_parseTranslationUnit2(
3131 CXIndex CIdx,
3132 const char *source_filename,
3133 const char *const *command_line_args,
3134 int num_command_line_args,
3135 struct CXUnsavedFile *unsaved_files,
3136 unsigned num_unsaved_files,
3137 unsigned options,
3138 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003139 LOG_FUNC_SECTION {
3140 *Log << source_filename << ": ";
3141 for (int i = 0; i != num_command_line_args; ++i)
3142 *Log << command_line_args[i] << " ";
3143 }
3144
Alp Toker9d85b182014-07-07 01:23:14 +00003145 if (num_unsaved_files && !unsaved_files)
3146 return CXError_InvalidArguments;
3147
Alp Toker5c532982014-07-07 22:42:03 +00003148 CXErrorCode result = CXError_Failure;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003149 auto ParseTranslationUnitImpl = [=, &result] {
3150 result = clang_parseTranslationUnit_Impl(
3151 CIdx, source_filename, command_line_args, num_command_line_args,
3152 llvm::makeArrayRef(unsaved_files, num_unsaved_files), options, out_TU);
3153 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003154 llvm::CrashRecoveryContext CRC;
3155
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003156 if (!RunSafely(CRC, ParseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003157 fprintf(stderr, "libclang: crash detected during parsing: {\n");
3158 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3159 fprintf(stderr, " 'command_line_args' : [");
3160 for (int i = 0; i != num_command_line_args; ++i) {
3161 if (i)
3162 fprintf(stderr, ", ");
3163 fprintf(stderr, "'%s'", command_line_args[i]);
3164 }
3165 fprintf(stderr, "],\n");
3166 fprintf(stderr, " 'unsaved_files' : [");
3167 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3168 if (i)
3169 fprintf(stderr, ", ");
3170 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3171 unsaved_files[i].Length);
3172 }
3173 fprintf(stderr, "],\n");
3174 fprintf(stderr, " 'options' : %d,\n", options);
3175 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003176
3177 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003178 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003179 if (CXTranslationUnit *TU = out_TU)
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003180 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003181 }
Alp Toker5c532982014-07-07 22:42:03 +00003182
3183 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003184}
3185
3186unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
3187 return CXSaveTranslationUnit_None;
3188}
3189
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003190static CXSaveError clang_saveTranslationUnit_Impl(CXTranslationUnit TU,
3191 const char *FileName,
3192 unsigned options) {
3193 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003194 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3195 setThreadBackgroundPriority();
3196
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003197 bool hadError = cxtu::getASTUnit(TU)->Save(FileName);
3198 return hadError ? CXSaveError_Unknown : CXSaveError_None;
Guy Benyei11169dd2012-12-18 14:30:41 +00003199}
3200
3201int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3202 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003203 LOG_FUNC_SECTION {
3204 *Log << TU << ' ' << FileName;
3205 }
3206
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003207 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003208 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003209 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003210 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003211
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003212 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003213 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3214 if (!CXXUnit->hasSema())
3215 return CXSaveError_InvalidTU;
3216
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003217 CXSaveError result;
3218 auto SaveTranslationUnitImpl = [=, &result]() {
3219 result = clang_saveTranslationUnit_Impl(TU, FileName, options);
3220 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003221
3222 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3223 getenv("LIBCLANG_NOTHREADS")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003224 SaveTranslationUnitImpl();
Guy Benyei11169dd2012-12-18 14:30:41 +00003225
3226 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3227 PrintLibclangResourceUsage(TU);
3228
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003229 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003230 }
3231
3232 // We have an AST that has invalid nodes due to compiler errors.
3233 // Use a crash recovery thread for protection.
3234
3235 llvm::CrashRecoveryContext CRC;
3236
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003237 if (!RunSafely(CRC, SaveTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003238 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3239 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3240 fprintf(stderr, " 'options' : %d,\n", options);
3241 fprintf(stderr, "}\n");
3242
3243 return CXSaveError_Unknown;
3244
3245 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3246 PrintLibclangResourceUsage(TU);
3247 }
3248
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003249 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003250}
3251
3252void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3253 if (CTUnit) {
3254 // If the translation unit has been marked as unsafe to free, just discard
3255 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003256 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3257 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003258 return;
3259
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003260 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003261 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003262 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3263 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003264 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003265 delete CTUnit;
3266 }
3267}
3268
3269unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3270 return CXReparse_None;
3271}
3272
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003273static CXErrorCode
3274clang_reparseTranslationUnit_Impl(CXTranslationUnit TU,
3275 ArrayRef<CXUnsavedFile> unsaved_files,
3276 unsigned options) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003277 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003278 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003279 LOG_BAD_TU(TU);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003280 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003281 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003282
3283 // Reset the associated diagnostics.
3284 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003285 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003286
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003287 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003288 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3289 setThreadBackgroundPriority();
3290
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003291 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003292 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003293
3294 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3295 new std::vector<ASTUnit::RemappedFile>());
3296
Guy Benyei11169dd2012-12-18 14:30:41 +00003297 // Recover resources if we crash before exiting this function.
3298 llvm::CrashRecoveryContextCleanupRegistrar<
3299 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003300
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003301 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003302 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003303 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003304 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003305 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003306
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003307 if (!CXXUnit->Reparse(CXXIdx->getPCHContainerOperations(),
3308 *RemappedFiles.get()))
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003309 return CXError_Success;
3310 if (isASTReadError(CXXUnit))
3311 return CXError_ASTReadError;
3312 return CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003313}
3314
3315int clang_reparseTranslationUnit(CXTranslationUnit TU,
3316 unsigned num_unsaved_files,
3317 struct CXUnsavedFile *unsaved_files,
3318 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003319 LOG_FUNC_SECTION {
3320 *Log << TU;
3321 }
3322
Alp Toker9d85b182014-07-07 01:23:14 +00003323 if (num_unsaved_files && !unsaved_files)
3324 return CXError_InvalidArguments;
3325
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003326 CXErrorCode result;
3327 auto ReparseTranslationUnitImpl = [=, &result]() {
3328 result = clang_reparseTranslationUnit_Impl(
3329 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options);
3330 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003331
3332 if (getenv("LIBCLANG_NOTHREADS")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003333 ReparseTranslationUnitImpl();
Alp Toker5c532982014-07-07 22:42:03 +00003334 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003335 }
3336
3337 llvm::CrashRecoveryContext CRC;
3338
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003339 if (!RunSafely(CRC, ReparseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003340 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003341 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003342 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003343 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3344 PrintLibclangResourceUsage(TU);
3345
Alp Toker5c532982014-07-07 22:42:03 +00003346 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003347}
3348
3349
3350CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003351 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003352 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003353 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003354 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003355
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003356 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003357 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003358}
3359
3360CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003361 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003362 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003363 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003364 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003365
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003366 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003367 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3368}
3369
3370} // end: extern "C"
3371
3372//===----------------------------------------------------------------------===//
3373// CXFile Operations.
3374//===----------------------------------------------------------------------===//
3375
3376extern "C" {
3377CXString clang_getFileName(CXFile SFile) {
3378 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003379 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003380
3381 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003382 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003383}
3384
3385time_t clang_getFileTime(CXFile SFile) {
3386 if (!SFile)
3387 return 0;
3388
3389 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3390 return FEnt->getModificationTime();
3391}
3392
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003393CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003394 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003395 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003396 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003397 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003398
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003399 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003400
3401 FileManager &FMgr = CXXUnit->getFileManager();
3402 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3403}
3404
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003405unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3406 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003407 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003408 LOG_BAD_TU(TU);
3409 return 0;
3410 }
3411
3412 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003413 return 0;
3414
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003415 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003416 FileEntry *FEnt = static_cast<FileEntry *>(file);
3417 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3418 .isFileMultipleIncludeGuarded(FEnt);
3419}
3420
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003421int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3422 if (!file || !outID)
3423 return 1;
3424
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003425 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003426 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3427 outID->data[0] = ID.getDevice();
3428 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003429 outID->data[2] = FEnt->getModificationTime();
3430 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003431}
3432
Argyrios Kyrtzidisac3997e2014-08-16 00:26:19 +00003433int clang_File_isEqual(CXFile file1, CXFile file2) {
3434 if (file1 == file2)
3435 return true;
3436
3437 if (!file1 || !file2)
3438 return false;
3439
3440 FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
3441 FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
3442 return FEnt1->getUniqueID() == FEnt2->getUniqueID();
3443}
3444
Guy Benyei11169dd2012-12-18 14:30:41 +00003445} // end: extern "C"
3446
3447//===----------------------------------------------------------------------===//
3448// CXCursor Operations.
3449//===----------------------------------------------------------------------===//
3450
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003451static const Decl *getDeclFromExpr(const Stmt *E) {
3452 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003453 return getDeclFromExpr(CE->getSubExpr());
3454
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003455 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003456 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003457 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003458 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003459 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003460 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003461 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003462 if (PRE->isExplicitProperty())
3463 return PRE->getExplicitProperty();
3464 // It could be messaging both getter and setter as in:
3465 // ++myobj.myprop;
3466 // in which case prefer to associate the setter since it is less obvious
3467 // from inspecting the source that the setter is going to get called.
3468 if (PRE->isMessagingSetter())
3469 return PRE->getImplicitPropertySetter();
3470 return PRE->getImplicitPropertyGetter();
3471 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003472 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003473 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003474 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003475 if (Expr *Src = OVE->getSourceExpr())
3476 return getDeclFromExpr(Src);
3477
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003478 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003479 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003480 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003481 if (!CE->isElidable())
3482 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003483 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003484 return OME->getMethodDecl();
3485
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003486 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003487 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003488 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003489 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3490 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003491 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003492 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3493 isa<ParmVarDecl>(SizeOfPack->getPack()))
3494 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003495
3496 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003497}
3498
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003499static SourceLocation getLocationFromExpr(const Expr *E) {
3500 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003501 return getLocationFromExpr(CE->getSubExpr());
3502
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003503 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003504 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003505 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003506 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003507 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003508 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003509 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003510 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003511 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003512 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003513 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003514 return PropRef->getLocation();
3515
3516 return E->getLocStart();
3517}
3518
3519extern "C" {
3520
3521unsigned clang_visitChildren(CXCursor parent,
3522 CXCursorVisitor visitor,
3523 CXClientData client_data) {
3524 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3525 /*VisitPreprocessorLast=*/false);
3526 return CursorVis.VisitChildren(parent);
3527}
3528
3529#ifndef __has_feature
3530#define __has_feature(x) 0
3531#endif
3532#if __has_feature(blocks)
3533typedef enum CXChildVisitResult
3534 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3535
3536static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3537 CXClientData client_data) {
3538 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3539 return block(cursor, parent);
3540}
3541#else
3542// If we are compiled with a compiler that doesn't have native blocks support,
3543// define and call the block manually, so the
3544typedef struct _CXChildVisitResult
3545{
3546 void *isa;
3547 int flags;
3548 int reserved;
3549 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3550 CXCursor);
3551} *CXCursorVisitorBlock;
3552
3553static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3554 CXClientData client_data) {
3555 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3556 return block->invoke(block, cursor, parent);
3557}
3558#endif
3559
3560
3561unsigned clang_visitChildrenWithBlock(CXCursor parent,
3562 CXCursorVisitorBlock block) {
3563 return clang_visitChildren(parent, visitWithBlock, block);
3564}
3565
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003566static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003567 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003568 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003569
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003570 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003571 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003572 if (const ObjCPropertyImplDecl *PropImpl =
3573 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003574 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003575 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003576
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003577 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003578 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003579 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003580
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003581 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003582 }
3583
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003584 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003585 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003586
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003587 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003588 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3589 // and returns different names. NamedDecl returns the class name and
3590 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003591 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003592
3593 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003594 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003595
3596 SmallString<1024> S;
3597 llvm::raw_svector_ostream os(S);
3598 ND->printName(os);
3599
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003600 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003601}
3602
3603CXString clang_getCursorSpelling(CXCursor C) {
3604 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003605 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003606
3607 if (clang_isReference(C.kind)) {
3608 switch (C.kind) {
3609 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003610 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003611 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003612 }
3613 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003614 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003615 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003616 }
3617 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003618 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003619 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003620 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003621 }
3622 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003623 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003624 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003625 }
3626 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003627 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003628 assert(Type && "Missing type decl");
3629
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003630 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003631 getAsString());
3632 }
3633 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003634 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003635 assert(Template && "Missing template decl");
3636
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003637 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003638 }
3639
3640 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003641 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003642 assert(NS && "Missing namespace decl");
3643
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003644 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003645 }
3646
3647 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003648 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003649 assert(Field && "Missing member decl");
3650
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003651 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003652 }
3653
3654 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003655 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003656 assert(Label && "Missing label");
3657
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003658 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003659 }
3660
3661 case CXCursor_OverloadedDeclRef: {
3662 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003663 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3664 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003665 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003666 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003667 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003668 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003669 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003670 OverloadedTemplateStorage *Ovl
3671 = Storage.get<OverloadedTemplateStorage*>();
3672 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003673 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003674 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003675 }
3676
3677 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003678 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003679 assert(Var && "Missing variable decl");
3680
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003681 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003682 }
3683
3684 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003685 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003686 }
3687 }
3688
3689 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003690 const Expr *E = getCursorExpr(C);
3691
3692 if (C.kind == CXCursor_ObjCStringLiteral ||
3693 C.kind == CXCursor_StringLiteral) {
3694 const StringLiteral *SLit;
3695 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3696 SLit = OSL->getString();
3697 } else {
3698 SLit = cast<StringLiteral>(E);
3699 }
3700 SmallString<256> Buf;
3701 llvm::raw_svector_ostream OS(Buf);
3702 SLit->outputString(OS);
3703 return cxstring::createDup(OS.str());
3704 }
3705
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003706 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003707 if (D)
3708 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003709 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003710 }
3711
3712 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003713 const Stmt *S = getCursorStmt(C);
3714 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003715 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003716
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003717 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003718 }
3719
3720 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003721 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003722 ->getNameStart());
3723
3724 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003725 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003726 ->getNameStart());
3727
3728 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003729 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003730
3731 if (clang_isDeclaration(C.kind))
3732 return getDeclSpelling(getCursorDecl(C));
3733
3734 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003735 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003736 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003737 }
3738
3739 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003740 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003741 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003742 }
3743
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003744 if (C.kind == CXCursor_PackedAttr) {
3745 return cxstring::createRef("packed");
3746 }
3747
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003748 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003749}
3750
3751CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3752 unsigned pieceIndex,
3753 unsigned options) {
3754 if (clang_Cursor_isNull(C))
3755 return clang_getNullRange();
3756
3757 ASTContext &Ctx = getCursorContext(C);
3758
3759 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003760 const Stmt *S = getCursorStmt(C);
3761 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003762 if (pieceIndex > 0)
3763 return clang_getNullRange();
3764 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3765 }
3766
3767 return clang_getNullRange();
3768 }
3769
3770 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003771 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003772 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3773 if (pieceIndex >= ME->getNumSelectorLocs())
3774 return clang_getNullRange();
3775 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3776 }
3777 }
3778
3779 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3780 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003781 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003782 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3783 if (pieceIndex >= MD->getNumSelectorLocs())
3784 return clang_getNullRange();
3785 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3786 }
3787 }
3788
3789 if (C.kind == CXCursor_ObjCCategoryDecl ||
3790 C.kind == CXCursor_ObjCCategoryImplDecl) {
3791 if (pieceIndex > 0)
3792 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003793 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003794 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3795 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003796 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003797 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3798 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3799 }
3800
3801 if (C.kind == CXCursor_ModuleImportDecl) {
3802 if (pieceIndex > 0)
3803 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003804 if (const ImportDecl *ImportD =
3805 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003806 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3807 if (!Locs.empty())
3808 return cxloc::translateSourceRange(Ctx,
3809 SourceRange(Locs.front(), Locs.back()));
3810 }
3811 return clang_getNullRange();
3812 }
3813
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00003814 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
3815 C.kind == CXCursor_ConversionFunction) {
3816 if (pieceIndex > 0)
3817 return clang_getNullRange();
3818 if (const FunctionDecl *FD =
3819 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
3820 DeclarationNameInfo FunctionName = FD->getNameInfo();
3821 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
3822 }
3823 return clang_getNullRange();
3824 }
3825
Guy Benyei11169dd2012-12-18 14:30:41 +00003826 // FIXME: A CXCursor_InclusionDirective should give the location of the
3827 // filename, but we don't keep track of this.
3828
3829 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3830 // but we don't keep track of this.
3831
3832 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3833 // but we don't keep track of this.
3834
3835 // Default handling, give the location of the cursor.
3836
3837 if (pieceIndex > 0)
3838 return clang_getNullRange();
3839
3840 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3841 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3842 return cxloc::translateSourceRange(Ctx, Loc);
3843}
3844
Eli Bendersky44a206f2014-07-31 18:04:56 +00003845CXString clang_Cursor_getMangling(CXCursor C) {
3846 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
3847 return cxstring::createEmpty();
3848
Eli Bendersky44a206f2014-07-31 18:04:56 +00003849 // Mangling only works for functions and variables.
Eli Bendersky79759592014-08-01 15:01:10 +00003850 const Decl *D = getCursorDecl(C);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003851 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
3852 return cxstring::createEmpty();
3853
Eli Bendersky79759592014-08-01 15:01:10 +00003854 // First apply frontend mangling.
Eli Bendersky44a206f2014-07-31 18:04:56 +00003855 const NamedDecl *ND = cast<NamedDecl>(D);
Eli Bendersky79759592014-08-01 15:01:10 +00003856 ASTContext &Ctx = ND->getASTContext();
3857 std::unique_ptr<MangleContext> MC(Ctx.createMangleContext());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003858
Eli Bendersky79759592014-08-01 15:01:10 +00003859 std::string FrontendBuf;
3860 llvm::raw_string_ostream FrontendBufOS(FrontendBuf);
3861 MC->mangleName(ND, FrontendBufOS);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003862
Eli Bendersky79759592014-08-01 15:01:10 +00003863 // Now apply backend mangling.
3864 std::unique_ptr<llvm::DataLayout> DL(
3865 new llvm::DataLayout(Ctx.getTargetInfo().getTargetDescription()));
Eli Bendersky79759592014-08-01 15:01:10 +00003866
3867 std::string FinalBuf;
3868 llvm::raw_string_ostream FinalBufOS(FinalBuf);
Rafael Espindolab633d202015-06-23 13:59:36 +00003869 llvm::Mangler::getNameWithPrefix(FinalBufOS, llvm::Twine(FrontendBufOS.str()),
3870 *DL);
Eli Bendersky79759592014-08-01 15:01:10 +00003871
3872 return cxstring::createDup(FinalBufOS.str());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003873}
3874
Guy Benyei11169dd2012-12-18 14:30:41 +00003875CXString clang_getCursorDisplayName(CXCursor C) {
3876 if (!clang_isDeclaration(C.kind))
3877 return clang_getCursorSpelling(C);
3878
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003879 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003880 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003881 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003882
3883 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003884 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003885 D = FunTmpl->getTemplatedDecl();
3886
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003887 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003888 SmallString<64> Str;
3889 llvm::raw_svector_ostream OS(Str);
3890 OS << *Function;
3891 if (Function->getPrimaryTemplate())
3892 OS << "<>";
3893 OS << "(";
3894 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3895 if (I)
3896 OS << ", ";
3897 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3898 }
3899
3900 if (Function->isVariadic()) {
3901 if (Function->getNumParams())
3902 OS << ", ";
3903 OS << "...";
3904 }
3905 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003906 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003907 }
3908
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003909 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003910 SmallString<64> Str;
3911 llvm::raw_svector_ostream OS(Str);
3912 OS << *ClassTemplate;
3913 OS << "<";
3914 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3915 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3916 if (I)
3917 OS << ", ";
3918
3919 NamedDecl *Param = Params->getParam(I);
3920 if (Param->getIdentifier()) {
3921 OS << Param->getIdentifier()->getName();
3922 continue;
3923 }
3924
3925 // There is no parameter name, which makes this tricky. Try to come up
3926 // with something useful that isn't too long.
3927 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3928 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3929 else if (NonTypeTemplateParmDecl *NTTP
3930 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3931 OS << NTTP->getType().getAsString(Policy);
3932 else
3933 OS << "template<...> class";
3934 }
3935
3936 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003937 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003938 }
3939
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003940 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003941 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3942 // If the type was explicitly written, use that.
3943 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003944 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003945
Benjamin Kramer9170e912013-02-22 15:46:01 +00003946 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003947 llvm::raw_svector_ostream OS(Str);
3948 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003949 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003950 ClassSpec->getTemplateArgs().data(),
3951 ClassSpec->getTemplateArgs().size(),
3952 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003953 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003954 }
3955
3956 return clang_getCursorSpelling(C);
3957}
3958
3959CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3960 switch (Kind) {
3961 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003962 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003963 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003964 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003965 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003966 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003967 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003968 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003969 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003970 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003971 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003972 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003973 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003974 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003975 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003976 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003977 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003978 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003979 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003980 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003981 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003982 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003983 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003984 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003985 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003986 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003987 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003988 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003989 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003990 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003991 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003992 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003993 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003994 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003995 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003996 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003997 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003998 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003999 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004000 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00004001 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004002 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004003 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004004 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004005 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004006 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004007 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004008 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004009 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004010 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004011 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004012 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004013 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004014 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004015 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004016 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004017 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004018 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004019 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004020 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004021 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004022 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004023 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004024 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004025 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004026 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004027 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004028 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004029 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004030 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004031 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004032 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004033 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004034 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004035 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004036 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004037 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004038 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004039 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004040 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004041 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004042 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004043 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004044 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004045 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004046 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004047 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004048 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004049 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004050 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004051 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004052 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004053 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004054 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004055 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004056 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004057 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004058 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004059 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004060 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004061 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004062 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004063 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004064 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004065 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004066 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004067 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004068 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004069 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004070 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004071 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004072 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004073 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004074 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004075 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004076 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004077 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004078 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004079 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004080 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004081 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004082 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004083 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004084 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004085 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004086 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004087 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004088 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00004089 case CXCursor_ObjCSelfExpr:
4090 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004091 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004092 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004093 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004094 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004095 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004096 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004097 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004098 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004099 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004100 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004101 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004102 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004103 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004104 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004105 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004106 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004107 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004108 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004109 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004110 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004111 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004112 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004113 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004114 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004115 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004116 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004117 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004118 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004119 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004120 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004121 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004122 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004123 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004124 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004125 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004126 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004127 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004128 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004129 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004130 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004131 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004132 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004133 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004134 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004135 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004136 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004137 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004138 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004139 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004140 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004141 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004142 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004143 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004144 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004145 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004146 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004147 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004148 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004149 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004150 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004151 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004152 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004153 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004154 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004155 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004156 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004157 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004158 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004159 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004160 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004161 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004162 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004163 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004164 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004165 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004166 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004167 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004168 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004169 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004170 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004171 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004172 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004173 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004174 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004175 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004176 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004177 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004178 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00004179 case CXCursor_SEHLeaveStmt:
4180 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004181 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004182 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004183 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004184 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00004185 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004186 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00004187 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004188 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00004189 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004190 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00004191 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004192 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00004193 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004194 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004195 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004196 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004197 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004198 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004199 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004200 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004201 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004202 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004203 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004204 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004205 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004206 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004207 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004208 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004209 case CXCursor_PackedAttr:
4210 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00004211 case CXCursor_PureAttr:
4212 return cxstring::createRef("attribute(pure)");
4213 case CXCursor_ConstAttr:
4214 return cxstring::createRef("attribute(const)");
4215 case CXCursor_NoDuplicateAttr:
4216 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00004217 case CXCursor_CUDAConstantAttr:
4218 return cxstring::createRef("attribute(constant)");
4219 case CXCursor_CUDADeviceAttr:
4220 return cxstring::createRef("attribute(device)");
4221 case CXCursor_CUDAGlobalAttr:
4222 return cxstring::createRef("attribute(global)");
4223 case CXCursor_CUDAHostAttr:
4224 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00004225 case CXCursor_CUDASharedAttr:
4226 return cxstring::createRef("attribute(shared)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004227 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004228 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004229 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004230 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00004231 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004232 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004233 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004234 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004235 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004236 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00004237 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004238 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00004239 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004240 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004241 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004242 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004243 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004244 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004245 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004246 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004247 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004248 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004249 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004250 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004251 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004252 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004253 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004254 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004255 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004256 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004257 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004258 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004259 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004260 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004261 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004262 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004263 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004264 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004265 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004266 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004267 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004268 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004269 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004270 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004271 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004272 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004273 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004274 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004275 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004276 return cxstring::createRef("OMPParallelDirective");
4277 case CXCursor_OMPSimdDirective:
4278 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004279 case CXCursor_OMPForDirective:
4280 return cxstring::createRef("OMPForDirective");
Alexander Musmanf82886e2014-09-18 05:12:34 +00004281 case CXCursor_OMPForSimdDirective:
4282 return cxstring::createRef("OMPForSimdDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004283 case CXCursor_OMPSectionsDirective:
4284 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004285 case CXCursor_OMPSectionDirective:
4286 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004287 case CXCursor_OMPSingleDirective:
4288 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004289 case CXCursor_OMPMasterDirective:
4290 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004291 case CXCursor_OMPCriticalDirective:
4292 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004293 case CXCursor_OMPParallelForDirective:
4294 return cxstring::createRef("OMPParallelForDirective");
Alexander Musmane4e893b2014-09-23 09:33:00 +00004295 case CXCursor_OMPParallelForSimdDirective:
4296 return cxstring::createRef("OMPParallelForSimdDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004297 case CXCursor_OMPParallelSectionsDirective:
4298 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004299 case CXCursor_OMPTaskDirective:
4300 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004301 case CXCursor_OMPTaskyieldDirective:
4302 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004303 case CXCursor_OMPBarrierDirective:
4304 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004305 case CXCursor_OMPTaskwaitDirective:
4306 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00004307 case CXCursor_OMPTaskgroupDirective:
4308 return cxstring::createRef("OMPTaskgroupDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00004309 case CXCursor_OMPFlushDirective:
4310 return cxstring::createRef("OMPFlushDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004311 case CXCursor_OMPOrderedDirective:
4312 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00004313 case CXCursor_OMPAtomicDirective:
4314 return cxstring::createRef("OMPAtomicDirective");
Alexey Bataev0bd520b2014-09-19 08:19:49 +00004315 case CXCursor_OMPTargetDirective:
4316 return cxstring::createRef("OMPTargetDirective");
Michael Wong65f367f2015-07-21 13:44:28 +00004317 case CXCursor_OMPTargetDataDirective:
4318 return cxstring::createRef("OMPTargetDataDirective");
Alexey Bataev13314bf2014-10-09 04:18:56 +00004319 case CXCursor_OMPTeamsDirective:
4320 return cxstring::createRef("OMPTeamsDirective");
Alexey Bataev6d4ed052015-07-01 06:57:41 +00004321 case CXCursor_OMPCancellationPointDirective:
4322 return cxstring::createRef("OMPCancellationPointDirective");
Alexey Bataev80909872015-07-02 11:25:17 +00004323 case CXCursor_OMPCancelDirective:
4324 return cxstring::createRef("OMPCancelDirective");
Francisco Lopes da Silva975a9f62015-01-21 16:24:11 +00004325 case CXCursor_OverloadCandidate:
4326 return cxstring::createRef("OverloadCandidate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004327 }
4328
4329 llvm_unreachable("Unhandled CXCursorKind");
4330}
4331
4332struct GetCursorData {
4333 SourceLocation TokenBeginLoc;
4334 bool PointsAtMacroArgExpansion;
4335 bool VisitedObjCPropertyImplDecl;
4336 SourceLocation VisitedDeclaratorDeclStartLoc;
4337 CXCursor &BestCursor;
4338
4339 GetCursorData(SourceManager &SM,
4340 SourceLocation tokenBegin, CXCursor &outputCursor)
4341 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4342 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4343 VisitedObjCPropertyImplDecl = false;
4344 }
4345};
4346
4347static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4348 CXCursor parent,
4349 CXClientData client_data) {
4350 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4351 CXCursor *BestCursor = &Data->BestCursor;
4352
4353 // If we point inside a macro argument we should provide info of what the
4354 // token is so use the actual cursor, don't replace it with a macro expansion
4355 // cursor.
4356 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4357 return CXChildVisit_Recurse;
4358
4359 if (clang_isDeclaration(cursor.kind)) {
4360 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004361 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004362 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4363 if (MD->isImplicit())
4364 return CXChildVisit_Break;
4365
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004366 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004367 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4368 // Check that when we have multiple @class references in the same line,
4369 // that later ones do not override the previous ones.
4370 // If we have:
4371 // @class Foo, Bar;
4372 // source ranges for both start at '@', so 'Bar' will end up overriding
4373 // 'Foo' even though the cursor location was at 'Foo'.
4374 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4375 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004376 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004377 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4378 if (PrevID != ID &&
4379 !PrevID->isThisDeclarationADefinition() &&
4380 !ID->isThisDeclarationADefinition())
4381 return CXChildVisit_Break;
4382 }
4383
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004384 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004385 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4386 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4387 // Check that when we have multiple declarators in the same line,
4388 // that later ones do not override the previous ones.
4389 // If we have:
4390 // int Foo, Bar;
4391 // source ranges for both start at 'int', so 'Bar' will end up overriding
4392 // 'Foo' even though the cursor location was at 'Foo'.
4393 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4394 return CXChildVisit_Break;
4395 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4396
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004397 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004398 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4399 (void)PropImp;
4400 // Check that when we have multiple @synthesize in the same line,
4401 // that later ones do not override the previous ones.
4402 // If we have:
4403 // @synthesize Foo, Bar;
4404 // source ranges for both start at '@', so 'Bar' will end up overriding
4405 // 'Foo' even though the cursor location was at 'Foo'.
4406 if (Data->VisitedObjCPropertyImplDecl)
4407 return CXChildVisit_Break;
4408 Data->VisitedObjCPropertyImplDecl = true;
4409 }
4410 }
4411
4412 if (clang_isExpression(cursor.kind) &&
4413 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004414 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004415 // Avoid having the cursor of an expression replace the declaration cursor
4416 // when the expression source range overlaps the declaration range.
4417 // This can happen for C++ constructor expressions whose range generally
4418 // include the variable declaration, e.g.:
4419 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4420 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4421 D->getLocation() == Data->TokenBeginLoc)
4422 return CXChildVisit_Break;
4423 }
4424 }
4425
4426 // If our current best cursor is the construction of a temporary object,
4427 // don't replace that cursor with a type reference, because we want
4428 // clang_getCursor() to point at the constructor.
4429 if (clang_isExpression(BestCursor->kind) &&
4430 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4431 cursor.kind == CXCursor_TypeRef) {
4432 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4433 // as having the actual point on the type reference.
4434 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4435 return CXChildVisit_Recurse;
4436 }
Douglas Gregore9d95f12015-07-07 03:57:35 +00004437
4438 // If we already have an Objective-C superclass reference, don't
4439 // update it further.
4440 if (BestCursor->kind == CXCursor_ObjCSuperClassRef)
4441 return CXChildVisit_Break;
4442
Guy Benyei11169dd2012-12-18 14:30:41 +00004443 *BestCursor = cursor;
4444 return CXChildVisit_Recurse;
4445}
4446
4447CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004448 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004449 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004450 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004451 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004452
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004453 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004454 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4455
4456 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4457 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4458
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004459 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004460 CXFile SearchFile;
4461 unsigned SearchLine, SearchColumn;
4462 CXFile ResultFile;
4463 unsigned ResultLine, ResultColumn;
4464 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4465 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4466 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004467
4468 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4469 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004470 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004471 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004472 SearchFileName = clang_getFileName(SearchFile);
4473 ResultFileName = clang_getFileName(ResultFile);
4474 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4475 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004476 *Log << llvm::format("(%s:%d:%d) = %s",
4477 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4478 clang_getCString(KindSpelling))
4479 << llvm::format("(%s:%d:%d):%s%s",
4480 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4481 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004482 clang_disposeString(SearchFileName);
4483 clang_disposeString(ResultFileName);
4484 clang_disposeString(KindSpelling);
4485 clang_disposeString(USR);
4486
4487 CXCursor Definition = clang_getCursorDefinition(Result);
4488 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4489 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4490 CXString DefinitionKindSpelling
4491 = clang_getCursorKindSpelling(Definition.kind);
4492 CXFile DefinitionFile;
4493 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004494 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004495 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004496 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004497 *Log << llvm::format(" -> %s(%s:%d:%d)",
4498 clang_getCString(DefinitionKindSpelling),
4499 clang_getCString(DefinitionFileName),
4500 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004501 clang_disposeString(DefinitionFileName);
4502 clang_disposeString(DefinitionKindSpelling);
4503 }
4504 }
4505
4506 return Result;
4507}
4508
4509CXCursor clang_getNullCursor(void) {
4510 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4511}
4512
4513unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004514 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4515 // can't set consistently. For example, when visiting a DeclStmt we will set
4516 // it but we don't set it on the result of clang_getCursorDefinition for
4517 // a reference of the same declaration.
4518 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4519 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4520 // to provide that kind of info.
4521 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004522 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004523 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004524 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004525
Guy Benyei11169dd2012-12-18 14:30:41 +00004526 return X == Y;
4527}
4528
4529unsigned clang_hashCursor(CXCursor C) {
4530 unsigned Index = 0;
4531 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4532 Index = 1;
4533
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004534 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004535 std::make_pair(C.kind, C.data[Index]));
4536}
4537
4538unsigned clang_isInvalid(enum CXCursorKind K) {
4539 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4540}
4541
4542unsigned clang_isDeclaration(enum CXCursorKind K) {
4543 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4544 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4545}
4546
4547unsigned clang_isReference(enum CXCursorKind K) {
4548 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4549}
4550
4551unsigned clang_isExpression(enum CXCursorKind K) {
4552 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4553}
4554
4555unsigned clang_isStatement(enum CXCursorKind K) {
4556 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4557}
4558
4559unsigned clang_isAttribute(enum CXCursorKind K) {
4560 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4561}
4562
4563unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4564 return K == CXCursor_TranslationUnit;
4565}
4566
4567unsigned clang_isPreprocessing(enum CXCursorKind K) {
4568 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4569}
4570
4571unsigned clang_isUnexposed(enum CXCursorKind K) {
4572 switch (K) {
4573 case CXCursor_UnexposedDecl:
4574 case CXCursor_UnexposedExpr:
4575 case CXCursor_UnexposedStmt:
4576 case CXCursor_UnexposedAttr:
4577 return true;
4578 default:
4579 return false;
4580 }
4581}
4582
4583CXCursorKind clang_getCursorKind(CXCursor C) {
4584 return C.kind;
4585}
4586
4587CXSourceLocation clang_getCursorLocation(CXCursor C) {
4588 if (clang_isReference(C.kind)) {
4589 switch (C.kind) {
4590 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004591 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004592 = getCursorObjCSuperClassRef(C);
4593 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4594 }
4595
4596 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004597 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004598 = getCursorObjCProtocolRef(C);
4599 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4600 }
4601
4602 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004603 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004604 = getCursorObjCClassRef(C);
4605 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4606 }
4607
4608 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004609 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004610 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4611 }
4612
4613 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004614 std::pair<const TemplateDecl *, SourceLocation> P =
4615 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004616 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4617 }
4618
4619 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004620 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004621 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4622 }
4623
4624 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004625 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004626 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4627 }
4628
4629 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004630 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004631 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4632 }
4633
4634 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004635 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004636 if (!BaseSpec)
4637 return clang_getNullLocation();
4638
4639 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4640 return cxloc::translateSourceLocation(getCursorContext(C),
4641 TSInfo->getTypeLoc().getBeginLoc());
4642
4643 return cxloc::translateSourceLocation(getCursorContext(C),
4644 BaseSpec->getLocStart());
4645 }
4646
4647 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004648 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004649 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4650 }
4651
4652 case CXCursor_OverloadedDeclRef:
4653 return cxloc::translateSourceLocation(getCursorContext(C),
4654 getCursorOverloadedDeclRef(C).second);
4655
4656 default:
4657 // FIXME: Need a way to enumerate all non-reference cases.
4658 llvm_unreachable("Missed a reference kind");
4659 }
4660 }
4661
4662 if (clang_isExpression(C.kind))
4663 return cxloc::translateSourceLocation(getCursorContext(C),
4664 getLocationFromExpr(getCursorExpr(C)));
4665
4666 if (clang_isStatement(C.kind))
4667 return cxloc::translateSourceLocation(getCursorContext(C),
4668 getCursorStmt(C)->getLocStart());
4669
4670 if (C.kind == CXCursor_PreprocessingDirective) {
4671 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4672 return cxloc::translateSourceLocation(getCursorContext(C), L);
4673 }
4674
4675 if (C.kind == CXCursor_MacroExpansion) {
4676 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004677 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004678 return cxloc::translateSourceLocation(getCursorContext(C), L);
4679 }
4680
4681 if (C.kind == CXCursor_MacroDefinition) {
4682 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4683 return cxloc::translateSourceLocation(getCursorContext(C), L);
4684 }
4685
4686 if (C.kind == CXCursor_InclusionDirective) {
4687 SourceLocation L
4688 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4689 return cxloc::translateSourceLocation(getCursorContext(C), L);
4690 }
4691
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004692 if (clang_isAttribute(C.kind)) {
4693 SourceLocation L
4694 = cxcursor::getCursorAttr(C)->getLocation();
4695 return cxloc::translateSourceLocation(getCursorContext(C), L);
4696 }
4697
Guy Benyei11169dd2012-12-18 14:30:41 +00004698 if (!clang_isDeclaration(C.kind))
4699 return clang_getNullLocation();
4700
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004701 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004702 if (!D)
4703 return clang_getNullLocation();
4704
4705 SourceLocation Loc = D->getLocation();
4706 // FIXME: Multiple variables declared in a single declaration
4707 // currently lack the information needed to correctly determine their
4708 // ranges when accounting for the type-specifier. We use context
4709 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4710 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004711 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004712 if (!cxcursor::isFirstInDeclGroup(C))
4713 Loc = VD->getLocation();
4714 }
4715
4716 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004717 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004718 Loc = MD->getSelectorStartLoc();
4719
4720 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4721}
4722
4723} // end extern "C"
4724
4725CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4726 assert(TU);
4727
4728 // Guard against an invalid SourceLocation, or we may assert in one
4729 // of the following calls.
4730 if (SLoc.isInvalid())
4731 return clang_getNullCursor();
4732
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004733 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004734
4735 // Translate the given source location to make it point at the beginning of
4736 // the token under the cursor.
4737 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4738 CXXUnit->getASTContext().getLangOpts());
4739
4740 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4741 if (SLoc.isValid()) {
4742 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4743 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4744 /*VisitPreprocessorLast=*/true,
4745 /*VisitIncludedEntities=*/false,
4746 SourceLocation(SLoc));
4747 CursorVis.visitFileRegion();
4748 }
4749
4750 return Result;
4751}
4752
4753static SourceRange getRawCursorExtent(CXCursor C) {
4754 if (clang_isReference(C.kind)) {
4755 switch (C.kind) {
4756 case CXCursor_ObjCSuperClassRef:
4757 return getCursorObjCSuperClassRef(C).second;
4758
4759 case CXCursor_ObjCProtocolRef:
4760 return getCursorObjCProtocolRef(C).second;
4761
4762 case CXCursor_ObjCClassRef:
4763 return getCursorObjCClassRef(C).second;
4764
4765 case CXCursor_TypeRef:
4766 return getCursorTypeRef(C).second;
4767
4768 case CXCursor_TemplateRef:
4769 return getCursorTemplateRef(C).second;
4770
4771 case CXCursor_NamespaceRef:
4772 return getCursorNamespaceRef(C).second;
4773
4774 case CXCursor_MemberRef:
4775 return getCursorMemberRef(C).second;
4776
4777 case CXCursor_CXXBaseSpecifier:
4778 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4779
4780 case CXCursor_LabelRef:
4781 return getCursorLabelRef(C).second;
4782
4783 case CXCursor_OverloadedDeclRef:
4784 return getCursorOverloadedDeclRef(C).second;
4785
4786 case CXCursor_VariableRef:
4787 return getCursorVariableRef(C).second;
4788
4789 default:
4790 // FIXME: Need a way to enumerate all non-reference cases.
4791 llvm_unreachable("Missed a reference kind");
4792 }
4793 }
4794
4795 if (clang_isExpression(C.kind))
4796 return getCursorExpr(C)->getSourceRange();
4797
4798 if (clang_isStatement(C.kind))
4799 return getCursorStmt(C)->getSourceRange();
4800
4801 if (clang_isAttribute(C.kind))
4802 return getCursorAttr(C)->getRange();
4803
4804 if (C.kind == CXCursor_PreprocessingDirective)
4805 return cxcursor::getCursorPreprocessingDirective(C);
4806
4807 if (C.kind == CXCursor_MacroExpansion) {
4808 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004809 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004810 return TU->mapRangeFromPreamble(Range);
4811 }
4812
4813 if (C.kind == CXCursor_MacroDefinition) {
4814 ASTUnit *TU = getCursorASTUnit(C);
4815 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4816 return TU->mapRangeFromPreamble(Range);
4817 }
4818
4819 if (C.kind == CXCursor_InclusionDirective) {
4820 ASTUnit *TU = getCursorASTUnit(C);
4821 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4822 return TU->mapRangeFromPreamble(Range);
4823 }
4824
4825 if (C.kind == CXCursor_TranslationUnit) {
4826 ASTUnit *TU = getCursorASTUnit(C);
4827 FileID MainID = TU->getSourceManager().getMainFileID();
4828 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4829 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4830 return SourceRange(Start, End);
4831 }
4832
4833 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004834 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004835 if (!D)
4836 return SourceRange();
4837
4838 SourceRange R = D->getSourceRange();
4839 // FIXME: Multiple variables declared in a single declaration
4840 // currently lack the information needed to correctly determine their
4841 // ranges when accounting for the type-specifier. We use context
4842 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4843 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004844 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004845 if (!cxcursor::isFirstInDeclGroup(C))
4846 R.setBegin(VD->getLocation());
4847 }
4848 return R;
4849 }
4850 return SourceRange();
4851}
4852
4853/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4854/// the decl-specifier-seq for declarations.
4855static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4856 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004857 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004858 if (!D)
4859 return SourceRange();
4860
4861 SourceRange R = D->getSourceRange();
4862
4863 // Adjust the start of the location for declarations preceded by
4864 // declaration specifiers.
4865 SourceLocation StartLoc;
4866 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4867 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4868 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004869 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004870 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4871 StartLoc = TI->getTypeLoc().getLocStart();
4872 }
4873
4874 if (StartLoc.isValid() && R.getBegin().isValid() &&
4875 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4876 R.setBegin(StartLoc);
4877
4878 // FIXME: Multiple variables declared in a single declaration
4879 // currently lack the information needed to correctly determine their
4880 // ranges when accounting for the type-specifier. We use context
4881 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4882 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004883 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004884 if (!cxcursor::isFirstInDeclGroup(C))
4885 R.setBegin(VD->getLocation());
4886 }
4887
4888 return R;
4889 }
4890
4891 return getRawCursorExtent(C);
4892}
4893
4894extern "C" {
4895
4896CXSourceRange clang_getCursorExtent(CXCursor C) {
4897 SourceRange R = getRawCursorExtent(C);
4898 if (R.isInvalid())
4899 return clang_getNullRange();
4900
4901 return cxloc::translateSourceRange(getCursorContext(C), R);
4902}
4903
4904CXCursor clang_getCursorReferenced(CXCursor C) {
4905 if (clang_isInvalid(C.kind))
4906 return clang_getNullCursor();
4907
4908 CXTranslationUnit tu = getCursorTU(C);
4909 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004910 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004911 if (!D)
4912 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004913 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004914 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004915 if (const ObjCPropertyImplDecl *PropImpl =
4916 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004917 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4918 return MakeCXCursor(Property, tu);
4919
4920 return C;
4921 }
4922
4923 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004924 const Expr *E = getCursorExpr(C);
4925 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004926 if (D) {
4927 CXCursor declCursor = MakeCXCursor(D, tu);
4928 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4929 declCursor);
4930 return declCursor;
4931 }
4932
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004933 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004934 return MakeCursorOverloadedDeclRef(Ovl, tu);
4935
4936 return clang_getNullCursor();
4937 }
4938
4939 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004940 const Stmt *S = getCursorStmt(C);
4941 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004942 if (LabelDecl *label = Goto->getLabel())
4943 if (LabelStmt *labelS = label->getStmt())
4944 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4945
4946 return clang_getNullCursor();
4947 }
Richard Smith66a81862015-05-04 02:25:31 +00004948
Guy Benyei11169dd2012-12-18 14:30:41 +00004949 if (C.kind == CXCursor_MacroExpansion) {
Richard Smith66a81862015-05-04 02:25:31 +00004950 if (const MacroDefinitionRecord *Def =
4951 getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004952 return MakeMacroDefinitionCursor(Def, tu);
4953 }
4954
4955 if (!clang_isReference(C.kind))
4956 return clang_getNullCursor();
4957
4958 switch (C.kind) {
4959 case CXCursor_ObjCSuperClassRef:
4960 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4961
4962 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004963 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4964 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004965 return MakeCXCursor(Def, tu);
4966
4967 return MakeCXCursor(Prot, tu);
4968 }
4969
4970 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004971 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4972 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004973 return MakeCXCursor(Def, tu);
4974
4975 return MakeCXCursor(Class, tu);
4976 }
4977
4978 case CXCursor_TypeRef:
4979 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4980
4981 case CXCursor_TemplateRef:
4982 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4983
4984 case CXCursor_NamespaceRef:
4985 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4986
4987 case CXCursor_MemberRef:
4988 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4989
4990 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004991 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004992 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4993 tu ));
4994 }
4995
4996 case CXCursor_LabelRef:
4997 // FIXME: We end up faking the "parent" declaration here because we
4998 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004999 return MakeCXCursor(getCursorLabelRef(C).first,
5000 cxtu::getASTUnit(tu)->getASTContext()
5001 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00005002 tu);
5003
5004 case CXCursor_OverloadedDeclRef:
5005 return C;
5006
5007 case CXCursor_VariableRef:
5008 return MakeCXCursor(getCursorVariableRef(C).first, tu);
5009
5010 default:
5011 // We would prefer to enumerate all non-reference cursor kinds here.
5012 llvm_unreachable("Unhandled reference cursor kind");
5013 }
5014}
5015
5016CXCursor clang_getCursorDefinition(CXCursor C) {
5017 if (clang_isInvalid(C.kind))
5018 return clang_getNullCursor();
5019
5020 CXTranslationUnit TU = getCursorTU(C);
5021
5022 bool WasReference = false;
5023 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
5024 C = clang_getCursorReferenced(C);
5025 WasReference = true;
5026 }
5027
5028 if (C.kind == CXCursor_MacroExpansion)
5029 return clang_getCursorReferenced(C);
5030
5031 if (!clang_isDeclaration(C.kind))
5032 return clang_getNullCursor();
5033
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005034 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005035 if (!D)
5036 return clang_getNullCursor();
5037
5038 switch (D->getKind()) {
5039 // Declaration kinds that don't really separate the notions of
5040 // declaration and definition.
5041 case Decl::Namespace:
5042 case Decl::Typedef:
5043 case Decl::TypeAlias:
5044 case Decl::TypeAliasTemplate:
5045 case Decl::TemplateTypeParm:
5046 case Decl::EnumConstant:
5047 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00005048 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005049 case Decl::IndirectField:
5050 case Decl::ObjCIvar:
5051 case Decl::ObjCAtDefsField:
5052 case Decl::ImplicitParam:
5053 case Decl::ParmVar:
5054 case Decl::NonTypeTemplateParm:
5055 case Decl::TemplateTemplateParm:
5056 case Decl::ObjCCategoryImpl:
5057 case Decl::ObjCImplementation:
5058 case Decl::AccessSpec:
5059 case Decl::LinkageSpec:
5060 case Decl::ObjCPropertyImpl:
5061 case Decl::FileScopeAsm:
5062 case Decl::StaticAssert:
5063 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00005064 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00005065 case Decl::Label: // FIXME: Is this right??
5066 case Decl::ClassScopeFunctionSpecialization:
5067 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00005068 case Decl::OMPThreadPrivate:
Douglas Gregor85f3f952015-07-07 03:57:15 +00005069 case Decl::ObjCTypeParam:
Guy Benyei11169dd2012-12-18 14:30:41 +00005070 return C;
5071
5072 // Declaration kinds that don't make any sense here, but are
5073 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00005074 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005075 case Decl::TranslationUnit:
Richard Smithf19e1272015-03-07 00:04:49 +00005076 case Decl::ExternCContext:
Guy Benyei11169dd2012-12-18 14:30:41 +00005077 break;
5078
5079 // Declaration kinds for which the definition is not resolvable.
5080 case Decl::UnresolvedUsingTypename:
5081 case Decl::UnresolvedUsingValue:
5082 break;
5083
5084 case Decl::UsingDirective:
5085 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
5086 TU);
5087
5088 case Decl::NamespaceAlias:
5089 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
5090
5091 case Decl::Enum:
5092 case Decl::Record:
5093 case Decl::CXXRecord:
5094 case Decl::ClassTemplateSpecialization:
5095 case Decl::ClassTemplatePartialSpecialization:
5096 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
5097 return MakeCXCursor(Def, TU);
5098 return clang_getNullCursor();
5099
5100 case Decl::Function:
5101 case Decl::CXXMethod:
5102 case Decl::CXXConstructor:
5103 case Decl::CXXDestructor:
5104 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00005105 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005106 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00005107 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005108 return clang_getNullCursor();
5109 }
5110
Larisse Voufo39a1e502013-08-06 01:03:05 +00005111 case Decl::Var:
5112 case Decl::VarTemplateSpecialization:
5113 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00005114 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005115 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005116 return MakeCXCursor(Def, TU);
5117 return clang_getNullCursor();
5118 }
5119
5120 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00005121 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005122 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
5123 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
5124 return clang_getNullCursor();
5125 }
5126
5127 case Decl::ClassTemplate: {
5128 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
5129 ->getDefinition())
5130 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
5131 TU);
5132 return clang_getNullCursor();
5133 }
5134
Larisse Voufo39a1e502013-08-06 01:03:05 +00005135 case Decl::VarTemplate: {
5136 if (VarDecl *Def =
5137 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
5138 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
5139 return clang_getNullCursor();
5140 }
5141
Guy Benyei11169dd2012-12-18 14:30:41 +00005142 case Decl::Using:
5143 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
5144 D->getLocation(), TU);
5145
5146 case Decl::UsingShadow:
5147 return clang_getCursorDefinition(
5148 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
5149 TU));
5150
5151 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005152 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005153 if (Method->isThisDeclarationADefinition())
5154 return C;
5155
5156 // Dig out the method definition in the associated
5157 // @implementation, if we have it.
5158 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005159 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005160 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
5161 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
5162 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
5163 Method->isInstanceMethod()))
5164 if (Def->isThisDeclarationADefinition())
5165 return MakeCXCursor(Def, TU);
5166
5167 return clang_getNullCursor();
5168 }
5169
5170 case Decl::ObjCCategory:
5171 if (ObjCCategoryImplDecl *Impl
5172 = cast<ObjCCategoryDecl>(D)->getImplementation())
5173 return MakeCXCursor(Impl, TU);
5174 return clang_getNullCursor();
5175
5176 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005177 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005178 return MakeCXCursor(Def, TU);
5179 return clang_getNullCursor();
5180
5181 case Decl::ObjCInterface: {
5182 // There are two notions of a "definition" for an Objective-C
5183 // class: the interface and its implementation. When we resolved a
5184 // reference to an Objective-C class, produce the @interface as
5185 // the definition; when we were provided with the interface,
5186 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005187 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005188 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005189 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005190 return MakeCXCursor(Def, TU);
5191 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
5192 return MakeCXCursor(Impl, TU);
5193 return clang_getNullCursor();
5194 }
5195
5196 case Decl::ObjCProperty:
5197 // FIXME: We don't really know where to find the
5198 // ObjCPropertyImplDecls that implement this property.
5199 return clang_getNullCursor();
5200
5201 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005202 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005203 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005204 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005205 return MakeCXCursor(Def, TU);
5206
5207 return clang_getNullCursor();
5208
5209 case Decl::Friend:
5210 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
5211 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5212 return clang_getNullCursor();
5213
5214 case Decl::FriendTemplate:
5215 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
5216 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5217 return clang_getNullCursor();
5218 }
5219
5220 return clang_getNullCursor();
5221}
5222
5223unsigned clang_isCursorDefinition(CXCursor C) {
5224 if (!clang_isDeclaration(C.kind))
5225 return 0;
5226
5227 return clang_getCursorDefinition(C) == C;
5228}
5229
5230CXCursor clang_getCanonicalCursor(CXCursor C) {
5231 if (!clang_isDeclaration(C.kind))
5232 return C;
5233
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005234 if (const Decl *D = getCursorDecl(C)) {
5235 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005236 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5237 return MakeCXCursor(CatD, getCursorTU(C));
5238
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005239 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5240 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00005241 return MakeCXCursor(IFD, getCursorTU(C));
5242
5243 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5244 }
5245
5246 return C;
5247}
5248
5249int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5250 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5251}
5252
5253unsigned clang_getNumOverloadedDecls(CXCursor C) {
5254 if (C.kind != CXCursor_OverloadedDeclRef)
5255 return 0;
5256
5257 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005258 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005259 return E->getNumDecls();
5260
5261 if (OverloadedTemplateStorage *S
5262 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5263 return S->size();
5264
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005265 const Decl *D = Storage.get<const Decl *>();
5266 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005267 return Using->shadow_size();
5268
5269 return 0;
5270}
5271
5272CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5273 if (cursor.kind != CXCursor_OverloadedDeclRef)
5274 return clang_getNullCursor();
5275
5276 if (index >= clang_getNumOverloadedDecls(cursor))
5277 return clang_getNullCursor();
5278
5279 CXTranslationUnit TU = getCursorTU(cursor);
5280 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005281 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005282 return MakeCXCursor(E->decls_begin()[index], TU);
5283
5284 if (OverloadedTemplateStorage *S
5285 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5286 return MakeCXCursor(S->begin()[index], TU);
5287
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005288 const Decl *D = Storage.get<const Decl *>();
5289 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005290 // FIXME: This is, unfortunately, linear time.
5291 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5292 std::advance(Pos, index);
5293 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5294 }
5295
5296 return clang_getNullCursor();
5297}
5298
5299void clang_getDefinitionSpellingAndExtent(CXCursor C,
5300 const char **startBuf,
5301 const char **endBuf,
5302 unsigned *startLine,
5303 unsigned *startColumn,
5304 unsigned *endLine,
5305 unsigned *endColumn) {
5306 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005307 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005308 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5309
5310 SourceManager &SM = FD->getASTContext().getSourceManager();
5311 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5312 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5313 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5314 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5315 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5316 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5317}
5318
5319
5320CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5321 unsigned PieceIndex) {
5322 RefNamePieces Pieces;
5323
5324 switch (C.kind) {
5325 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005326 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005327 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5328 E->getQualifierLoc().getSourceRange());
5329 break;
5330
5331 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005332 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005333 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
5334 E->getQualifierLoc().getSourceRange(),
5335 E->getOptionalExplicitTemplateArgs());
5336 break;
5337
5338 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005339 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005340 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005341 const Expr *Callee = OCE->getCallee();
5342 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005343 Callee = ICE->getSubExpr();
5344
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005345 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005346 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5347 DRE->getQualifierLoc().getSourceRange());
5348 }
5349 break;
5350
5351 default:
5352 break;
5353 }
5354
5355 if (Pieces.empty()) {
5356 if (PieceIndex == 0)
5357 return clang_getCursorExtent(C);
5358 } else if (PieceIndex < Pieces.size()) {
5359 SourceRange R = Pieces[PieceIndex];
5360 if (R.isValid())
5361 return cxloc::translateSourceRange(getCursorContext(C), R);
5362 }
5363
5364 return clang_getNullRange();
5365}
5366
5367void clang_enableStackTraces(void) {
5368 llvm::sys::PrintStackTraceOnErrorSignal();
5369}
5370
5371void clang_executeOnThread(void (*fn)(void*), void *user_data,
5372 unsigned stack_size) {
5373 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5374}
5375
5376} // end: extern "C"
5377
5378//===----------------------------------------------------------------------===//
5379// Token-based Operations.
5380//===----------------------------------------------------------------------===//
5381
5382/* CXToken layout:
5383 * int_data[0]: a CXTokenKind
5384 * int_data[1]: starting token location
5385 * int_data[2]: token length
5386 * int_data[3]: reserved
5387 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5388 * otherwise unused.
5389 */
5390extern "C" {
5391
5392CXTokenKind clang_getTokenKind(CXToken CXTok) {
5393 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5394}
5395
5396CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5397 switch (clang_getTokenKind(CXTok)) {
5398 case CXToken_Identifier:
5399 case CXToken_Keyword:
5400 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005401 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005402 ->getNameStart());
5403
5404 case CXToken_Literal: {
5405 // We have stashed the starting pointer in the ptr_data field. Use it.
5406 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005407 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005408 }
5409
5410 case CXToken_Punctuation:
5411 case CXToken_Comment:
5412 break;
5413 }
5414
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005415 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005416 LOG_BAD_TU(TU);
5417 return cxstring::createEmpty();
5418 }
5419
Guy Benyei11169dd2012-12-18 14:30:41 +00005420 // We have to find the starting buffer pointer the hard way, by
5421 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005422 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005423 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005424 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005425
5426 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5427 std::pair<FileID, unsigned> LocInfo
5428 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5429 bool Invalid = false;
5430 StringRef Buffer
5431 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5432 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005433 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005434
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005435 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005436}
5437
5438CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005439 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005440 LOG_BAD_TU(TU);
5441 return clang_getNullLocation();
5442 }
5443
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005444 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005445 if (!CXXUnit)
5446 return clang_getNullLocation();
5447
5448 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5449 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5450}
5451
5452CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005453 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005454 LOG_BAD_TU(TU);
5455 return clang_getNullRange();
5456 }
5457
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005458 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005459 if (!CXXUnit)
5460 return clang_getNullRange();
5461
5462 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5463 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5464}
5465
5466static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5467 SmallVectorImpl<CXToken> &CXTokens) {
5468 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5469 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005470 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005471 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005472 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005473
5474 // Cannot tokenize across files.
5475 if (BeginLocInfo.first != EndLocInfo.first)
5476 return;
5477
5478 // Create a lexer
5479 bool Invalid = false;
5480 StringRef Buffer
5481 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5482 if (Invalid)
5483 return;
5484
5485 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5486 CXXUnit->getASTContext().getLangOpts(),
5487 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5488 Lex.SetCommentRetentionState(true);
5489
5490 // Lex tokens until we hit the end of the range.
5491 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5492 Token Tok;
5493 bool previousWasAt = false;
5494 do {
5495 // Lex the next token
5496 Lex.LexFromRawLexer(Tok);
5497 if (Tok.is(tok::eof))
5498 break;
5499
5500 // Initialize the CXToken.
5501 CXToken CXTok;
5502
5503 // - Common fields
5504 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5505 CXTok.int_data[2] = Tok.getLength();
5506 CXTok.int_data[3] = 0;
5507
5508 // - Kind-specific fields
5509 if (Tok.isLiteral()) {
5510 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005511 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005512 } else if (Tok.is(tok::raw_identifier)) {
5513 // Lookup the identifier to determine whether we have a keyword.
5514 IdentifierInfo *II
5515 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5516
5517 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5518 CXTok.int_data[0] = CXToken_Keyword;
5519 }
5520 else {
5521 CXTok.int_data[0] = Tok.is(tok::identifier)
5522 ? CXToken_Identifier
5523 : CXToken_Keyword;
5524 }
5525 CXTok.ptr_data = II;
5526 } else if (Tok.is(tok::comment)) {
5527 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005528 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005529 } else {
5530 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005531 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005532 }
5533 CXTokens.push_back(CXTok);
5534 previousWasAt = Tok.is(tok::at);
5535 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5536}
5537
5538void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5539 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005540 LOG_FUNC_SECTION {
5541 *Log << TU << ' ' << Range;
5542 }
5543
Guy Benyei11169dd2012-12-18 14:30:41 +00005544 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005545 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005546 if (NumTokens)
5547 *NumTokens = 0;
5548
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005549 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005550 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005551 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005552 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005553
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005554 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005555 if (!CXXUnit || !Tokens || !NumTokens)
5556 return;
5557
5558 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5559
5560 SourceRange R = cxloc::translateCXSourceRange(Range);
5561 if (R.isInvalid())
5562 return;
5563
5564 SmallVector<CXToken, 32> CXTokens;
5565 getTokens(CXXUnit, R, CXTokens);
5566
5567 if (CXTokens.empty())
5568 return;
5569
5570 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5571 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5572 *NumTokens = CXTokens.size();
5573}
5574
5575void clang_disposeTokens(CXTranslationUnit TU,
5576 CXToken *Tokens, unsigned NumTokens) {
5577 free(Tokens);
5578}
5579
5580} // end: extern "C"
5581
5582//===----------------------------------------------------------------------===//
5583// Token annotation APIs.
5584//===----------------------------------------------------------------------===//
5585
Guy Benyei11169dd2012-12-18 14:30:41 +00005586static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5587 CXCursor parent,
5588 CXClientData client_data);
5589static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5590 CXClientData client_data);
5591
5592namespace {
5593class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005594 CXToken *Tokens;
5595 CXCursor *Cursors;
5596 unsigned NumTokens;
5597 unsigned TokIdx;
5598 unsigned PreprocessingTokIdx;
5599 CursorVisitor AnnotateVis;
5600 SourceManager &SrcMgr;
5601 bool HasContextSensitiveKeywords;
5602
5603 struct PostChildrenInfo {
5604 CXCursor Cursor;
5605 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005606 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005607 unsigned BeforeChildrenTokenIdx;
5608 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005609 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005610
5611 CXToken &getTok(unsigned Idx) {
5612 assert(Idx < NumTokens);
5613 return Tokens[Idx];
5614 }
5615 const CXToken &getTok(unsigned Idx) const {
5616 assert(Idx < NumTokens);
5617 return Tokens[Idx];
5618 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005619 bool MoreTokens() const { return TokIdx < NumTokens; }
5620 unsigned NextToken() const { return TokIdx; }
5621 void AdvanceToken() { ++TokIdx; }
5622 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005623 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005624 }
5625 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005626 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005627 }
5628 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005629 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005630 }
5631
5632 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005633 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005634 SourceRange);
5635
5636public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005637 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005638 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005639 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005640 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005641 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005642 AnnotateTokensVisitor, this,
5643 /*VisitPreprocessorLast=*/true,
5644 /*VisitIncludedEntities=*/false,
5645 RegionOfInterest,
5646 /*VisitDeclsOnly=*/false,
5647 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005648 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005649 HasContextSensitiveKeywords(false) { }
5650
5651 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5652 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5653 bool postVisitChildren(CXCursor cursor);
5654 void AnnotateTokens();
5655
5656 /// \brief Determine whether the annotator saw any cursors that have
5657 /// context-sensitive keywords.
5658 bool hasContextSensitiveKeywords() const {
5659 return HasContextSensitiveKeywords;
5660 }
5661
5662 ~AnnotateTokensWorker() {
5663 assert(PostChildrenInfos.empty());
5664 }
5665};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00005666}
Guy Benyei11169dd2012-12-18 14:30:41 +00005667
5668void AnnotateTokensWorker::AnnotateTokens() {
5669 // Walk the AST within the region of interest, annotating tokens
5670 // along the way.
5671 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005672}
Guy Benyei11169dd2012-12-18 14:30:41 +00005673
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005674static inline void updateCursorAnnotation(CXCursor &Cursor,
5675 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005676 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005677 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005678 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005679}
5680
5681/// \brief It annotates and advances tokens with a cursor until the comparison
5682//// between the cursor location and the source range is the same as
5683/// \arg compResult.
5684///
5685/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5686/// Pass RangeOverlap to annotate tokens inside a range.
5687void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5688 RangeComparisonResult compResult,
5689 SourceRange range) {
5690 while (MoreTokens()) {
5691 const unsigned I = NextToken();
5692 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005693 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5694 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005695
5696 SourceLocation TokLoc = GetTokenLoc(I);
5697 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005698 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005699 AdvanceToken();
5700 continue;
5701 }
5702 break;
5703 }
5704}
5705
5706/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005707/// \returns true if it advanced beyond all macro tokens, false otherwise.
5708bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005709 CXCursor updateC,
5710 RangeComparisonResult compResult,
5711 SourceRange range) {
5712 assert(MoreTokens());
5713 assert(isFunctionMacroToken(NextToken()) &&
5714 "Should be called only for macro arg tokens");
5715
5716 // This works differently than annotateAndAdvanceTokens; because expanded
5717 // macro arguments can have arbitrary translation-unit source order, we do not
5718 // advance the token index one by one until a token fails the range test.
5719 // We only advance once past all of the macro arg tokens if all of them
5720 // pass the range test. If one of them fails we keep the token index pointing
5721 // at the start of the macro arg tokens so that the failing token will be
5722 // annotated by a subsequent annotation try.
5723
5724 bool atLeastOneCompFail = false;
5725
5726 unsigned I = NextToken();
5727 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5728 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5729 if (TokLoc.isFileID())
5730 continue; // not macro arg token, it's parens or comma.
5731 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5732 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5733 Cursors[I] = updateC;
5734 } else
5735 atLeastOneCompFail = true;
5736 }
5737
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005738 if (atLeastOneCompFail)
5739 return false;
5740
5741 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5742 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005743}
5744
5745enum CXChildVisitResult
5746AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005747 SourceRange cursorRange = getRawCursorExtent(cursor);
5748 if (cursorRange.isInvalid())
5749 return CXChildVisit_Recurse;
5750
5751 if (!HasContextSensitiveKeywords) {
5752 // Objective-C properties can have context-sensitive keywords.
5753 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005754 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005755 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5756 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5757 }
5758 // Objective-C methods can have context-sensitive keywords.
5759 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5760 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005761 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005762 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5763 if (Method->getObjCDeclQualifier())
5764 HasContextSensitiveKeywords = true;
5765 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005766 for (const auto *P : Method->params()) {
5767 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005768 HasContextSensitiveKeywords = true;
5769 break;
5770 }
5771 }
5772 }
5773 }
5774 }
5775 // C++ methods can have context-sensitive keywords.
5776 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005777 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005778 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5779 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5780 HasContextSensitiveKeywords = true;
5781 }
5782 }
5783 // C++ classes can have context-sensitive keywords.
5784 else if (cursor.kind == CXCursor_StructDecl ||
5785 cursor.kind == CXCursor_ClassDecl ||
5786 cursor.kind == CXCursor_ClassTemplate ||
5787 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005788 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005789 if (D->hasAttr<FinalAttr>())
5790 HasContextSensitiveKeywords = true;
5791 }
5792 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005793
5794 // Don't override a property annotation with its getter/setter method.
5795 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5796 parent.kind == CXCursor_ObjCPropertyDecl)
5797 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005798
5799 if (clang_isPreprocessing(cursor.kind)) {
5800 // Items in the preprocessing record are kept separate from items in
5801 // declarations, so we keep a separate token index.
5802 unsigned SavedTokIdx = TokIdx;
5803 TokIdx = PreprocessingTokIdx;
5804
5805 // Skip tokens up until we catch up to the beginning of the preprocessing
5806 // entry.
5807 while (MoreTokens()) {
5808 const unsigned I = NextToken();
5809 SourceLocation TokLoc = GetTokenLoc(I);
5810 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5811 case RangeBefore:
5812 AdvanceToken();
5813 continue;
5814 case RangeAfter:
5815 case RangeOverlap:
5816 break;
5817 }
5818 break;
5819 }
5820
5821 // Look at all of the tokens within this range.
5822 while (MoreTokens()) {
5823 const unsigned I = NextToken();
5824 SourceLocation TokLoc = GetTokenLoc(I);
5825 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5826 case RangeBefore:
5827 llvm_unreachable("Infeasible");
5828 case RangeAfter:
5829 break;
5830 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005831 // For macro expansions, just note where the beginning of the macro
5832 // expansion occurs.
5833 if (cursor.kind == CXCursor_MacroExpansion) {
5834 if (TokLoc == cursorRange.getBegin())
5835 Cursors[I] = cursor;
5836 AdvanceToken();
5837 break;
5838 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005839 // We may have already annotated macro names inside macro definitions.
5840 if (Cursors[I].kind != CXCursor_MacroExpansion)
5841 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005842 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005843 continue;
5844 }
5845 break;
5846 }
5847
5848 // Save the preprocessing token index; restore the non-preprocessing
5849 // token index.
5850 PreprocessingTokIdx = TokIdx;
5851 TokIdx = SavedTokIdx;
5852 return CXChildVisit_Recurse;
5853 }
5854
5855 if (cursorRange.isInvalid())
5856 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005857
5858 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005859 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005860 const enum CXCursorKind K = clang_getCursorKind(parent);
5861 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005862 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5863 // Attributes are annotated out-of-order, skip tokens until we reach it.
5864 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005865 ? clang_getNullCursor() : parent;
5866
5867 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5868
5869 // Avoid having the cursor of an expression "overwrite" the annotation of the
5870 // variable declaration that it belongs to.
5871 // This can happen for C++ constructor expressions whose range generally
5872 // include the variable declaration, e.g.:
5873 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005874 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005875 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005876 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005877 const unsigned I = NextToken();
5878 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5879 E->getLocStart() == D->getLocation() &&
5880 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005881 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005882 AdvanceToken();
5883 }
5884 }
5885 }
5886
5887 // Before recursing into the children keep some state that we are going
5888 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5889 // extra work after the child nodes are visited.
5890 // Note that we don't call VisitChildren here to avoid traversing statements
5891 // code-recursively which can blow the stack.
5892
5893 PostChildrenInfo Info;
5894 Info.Cursor = cursor;
5895 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005896 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005897 Info.BeforeChildrenTokenIdx = NextToken();
5898 PostChildrenInfos.push_back(Info);
5899
5900 return CXChildVisit_Recurse;
5901}
5902
5903bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5904 if (PostChildrenInfos.empty())
5905 return false;
5906 const PostChildrenInfo &Info = PostChildrenInfos.back();
5907 if (!clang_equalCursors(Info.Cursor, cursor))
5908 return false;
5909
5910 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5911 const unsigned AfterChildren = NextToken();
5912 SourceRange cursorRange = Info.CursorRange;
5913
5914 // Scan the tokens that are at the end of the cursor, but are not captured
5915 // but the child cursors.
5916 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5917
5918 // Scan the tokens that are at the beginning of the cursor, but are not
5919 // capture by the child cursors.
5920 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5921 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5922 break;
5923
5924 Cursors[I] = cursor;
5925 }
5926
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005927 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5928 // encountered the attribute cursor.
5929 if (clang_isAttribute(cursor.kind))
5930 TokIdx = Info.BeforeReachingCursorIdx;
5931
Guy Benyei11169dd2012-12-18 14:30:41 +00005932 PostChildrenInfos.pop_back();
5933 return false;
5934}
5935
5936static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5937 CXCursor parent,
5938 CXClientData client_data) {
5939 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5940}
5941
5942static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5943 CXClientData client_data) {
5944 return static_cast<AnnotateTokensWorker*>(client_data)->
5945 postVisitChildren(cursor);
5946}
5947
5948namespace {
5949
5950/// \brief Uses the macro expansions in the preprocessing record to find
5951/// and mark tokens that are macro arguments. This info is used by the
5952/// AnnotateTokensWorker.
5953class MarkMacroArgTokensVisitor {
5954 SourceManager &SM;
5955 CXToken *Tokens;
5956 unsigned NumTokens;
5957 unsigned CurIdx;
5958
5959public:
5960 MarkMacroArgTokensVisitor(SourceManager &SM,
5961 CXToken *tokens, unsigned numTokens)
5962 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5963
5964 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5965 if (cursor.kind != CXCursor_MacroExpansion)
5966 return CXChildVisit_Continue;
5967
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005968 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005969 if (macroRange.getBegin() == macroRange.getEnd())
5970 return CXChildVisit_Continue; // it's not a function macro.
5971
5972 for (; CurIdx < NumTokens; ++CurIdx) {
5973 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5974 macroRange.getBegin()))
5975 break;
5976 }
5977
5978 if (CurIdx == NumTokens)
5979 return CXChildVisit_Break;
5980
5981 for (; CurIdx < NumTokens; ++CurIdx) {
5982 SourceLocation tokLoc = getTokenLoc(CurIdx);
5983 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5984 break;
5985
5986 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5987 }
5988
5989 if (CurIdx == NumTokens)
5990 return CXChildVisit_Break;
5991
5992 return CXChildVisit_Continue;
5993 }
5994
5995private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005996 CXToken &getTok(unsigned Idx) {
5997 assert(Idx < NumTokens);
5998 return Tokens[Idx];
5999 }
6000 const CXToken &getTok(unsigned Idx) const {
6001 assert(Idx < NumTokens);
6002 return Tokens[Idx];
6003 }
6004
Guy Benyei11169dd2012-12-18 14:30:41 +00006005 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006006 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006007 }
6008
6009 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
6010 // The third field is reserved and currently not used. Use it here
6011 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006012 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00006013 }
6014};
6015
6016} // end anonymous namespace
6017
6018static CXChildVisitResult
6019MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
6020 CXClientData client_data) {
6021 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
6022 parent);
6023}
6024
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006025/// \brief Used by \c annotatePreprocessorTokens.
6026/// \returns true if lexing was finished, false otherwise.
6027static bool lexNext(Lexer &Lex, Token &Tok,
6028 unsigned &NextIdx, unsigned NumTokens) {
6029 if (NextIdx >= NumTokens)
6030 return true;
6031
6032 ++NextIdx;
6033 Lex.LexFromRawLexer(Tok);
6034 if (Tok.is(tok::eof))
6035 return true;
6036
6037 return false;
6038}
6039
Guy Benyei11169dd2012-12-18 14:30:41 +00006040static void annotatePreprocessorTokens(CXTranslationUnit TU,
6041 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006042 CXCursor *Cursors,
6043 CXToken *Tokens,
6044 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006045 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006046
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006047 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00006048 SourceManager &SourceMgr = CXXUnit->getSourceManager();
6049 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006050 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00006051 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006052 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00006053
6054 if (BeginLocInfo.first != EndLocInfo.first)
6055 return;
6056
6057 StringRef Buffer;
6058 bool Invalid = false;
6059 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
6060 if (Buffer.empty() || Invalid)
6061 return;
6062
6063 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
6064 CXXUnit->getASTContext().getLangOpts(),
6065 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
6066 Buffer.end());
6067 Lex.SetCommentRetentionState(true);
6068
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006069 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006070 // Lex tokens in raw mode until we hit the end of the range, to avoid
6071 // entering #includes or expanding macros.
6072 while (true) {
6073 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006074 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6075 break;
6076 unsigned TokIdx = NextIdx-1;
6077 assert(Tok.getLocation() ==
6078 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006079
6080 reprocess:
6081 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006082 // We have found a preprocessing directive. Annotate the tokens
6083 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00006084 //
6085 // FIXME: Some simple tests here could identify macro definitions and
6086 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006087
6088 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006089 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6090 break;
6091
Craig Topper69186e72014-06-08 08:38:04 +00006092 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00006093 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006094 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6095 break;
6096
6097 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00006098 IdentifierInfo &II =
6099 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006100 SourceLocation MappedTokLoc =
6101 CXXUnit->mapLocationToPreamble(Tok.getLocation());
6102 MI = getMacroInfo(II, MappedTokLoc, TU);
6103 }
6104 }
6105
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006106 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00006107 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006108 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
6109 finished = true;
6110 break;
6111 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006112 // If we are in a macro definition, check if the token was ever a
6113 // macro name and annotate it if that's the case.
6114 if (MI) {
6115 SourceLocation SaveLoc = Tok.getLocation();
6116 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
Richard Smith66a81862015-05-04 02:25:31 +00006117 MacroDefinitionRecord *MacroDef =
6118 checkForMacroInMacroDefinition(MI, Tok, TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006119 Tok.setLocation(SaveLoc);
6120 if (MacroDef)
Richard Smith66a81862015-05-04 02:25:31 +00006121 Cursors[NextIdx - 1] =
6122 MakeMacroExpansionCursor(MacroDef, Tok.getLocation(), TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006123 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006124 } while (!Tok.isAtStartOfLine());
6125
6126 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
6127 assert(TokIdx <= LastIdx);
6128 SourceLocation EndLoc =
6129 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
6130 CXCursor Cursor =
6131 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
6132
6133 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006134 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006135
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006136 if (finished)
6137 break;
6138 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00006139 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006140 }
6141}
6142
6143// This gets run a separate thread to avoid stack blowout.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006144static void clang_annotateTokensImpl(CXTranslationUnit TU, ASTUnit *CXXUnit,
6145 CXToken *Tokens, unsigned NumTokens,
6146 CXCursor *Cursors) {
Dmitri Gribenko183436e2013-01-26 21:49:50 +00006147 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006148 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
6149 setThreadBackgroundPriority();
6150
6151 // Determine the region of interest, which contains all of the tokens.
6152 SourceRange RegionOfInterest;
6153 RegionOfInterest.setBegin(
6154 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
6155 RegionOfInterest.setEnd(
6156 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
6157 Tokens[NumTokens-1])));
6158
Guy Benyei11169dd2012-12-18 14:30:41 +00006159 // Relex the tokens within the source range to look for preprocessing
6160 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006161 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006162
6163 // If begin location points inside a macro argument, set it to the expansion
6164 // location so we can have the full context when annotating semantically.
6165 {
6166 SourceManager &SM = CXXUnit->getSourceManager();
6167 SourceLocation Loc =
6168 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
6169 if (Loc.isMacroID())
6170 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
6171 }
6172
Guy Benyei11169dd2012-12-18 14:30:41 +00006173 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
6174 // Search and mark tokens that are macro argument expansions.
6175 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
6176 Tokens, NumTokens);
6177 CursorVisitor MacroArgMarker(TU,
6178 MarkMacroArgTokensVisitorDelegate, &Visitor,
6179 /*VisitPreprocessorLast=*/true,
6180 /*VisitIncludedEntities=*/false,
6181 RegionOfInterest);
6182 MacroArgMarker.visitPreprocessedEntitiesInRegion();
6183 }
6184
6185 // Annotate all of the source locations in the region of interest that map to
6186 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006187 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00006188
6189 // FIXME: We use a ridiculous stack size here because the data-recursion
6190 // algorithm uses a large stack frame than the non-data recursive version,
6191 // and AnnotationTokensWorker currently transforms the data-recursion
6192 // algorithm back into a traditional recursion by explicitly calling
6193 // VisitChildren(). We will need to remove this explicit recursive call.
6194 W.AnnotateTokens();
6195
6196 // If we ran into any entities that involve context-sensitive keywords,
6197 // take another pass through the tokens to mark them as such.
6198 if (W.hasContextSensitiveKeywords()) {
6199 for (unsigned I = 0; I != NumTokens; ++I) {
6200 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
6201 continue;
6202
6203 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
6204 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006205 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006206 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
6207 if (Property->getPropertyAttributesAsWritten() != 0 &&
6208 llvm::StringSwitch<bool>(II->getName())
6209 .Case("readonly", true)
6210 .Case("assign", true)
6211 .Case("unsafe_unretained", true)
6212 .Case("readwrite", true)
6213 .Case("retain", true)
6214 .Case("copy", true)
6215 .Case("nonatomic", true)
6216 .Case("atomic", true)
6217 .Case("getter", true)
6218 .Case("setter", true)
6219 .Case("strong", true)
6220 .Case("weak", true)
6221 .Default(false))
6222 Tokens[I].int_data[0] = CXToken_Keyword;
6223 }
6224 continue;
6225 }
6226
6227 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6228 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6229 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6230 if (llvm::StringSwitch<bool>(II->getName())
6231 .Case("in", true)
6232 .Case("out", true)
6233 .Case("inout", true)
6234 .Case("oneway", true)
6235 .Case("bycopy", true)
6236 .Case("byref", true)
6237 .Default(false))
6238 Tokens[I].int_data[0] = CXToken_Keyword;
6239 continue;
6240 }
6241
6242 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6243 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6244 Tokens[I].int_data[0] = CXToken_Keyword;
6245 continue;
6246 }
6247 }
6248 }
6249}
6250
6251extern "C" {
6252
6253void clang_annotateTokens(CXTranslationUnit TU,
6254 CXToken *Tokens, unsigned NumTokens,
6255 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006256 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006257 LOG_BAD_TU(TU);
6258 return;
6259 }
6260 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006261 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006262 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006263 }
6264
6265 LOG_FUNC_SECTION {
6266 *Log << TU << ' ';
6267 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6268 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6269 *Log << clang_getRange(bloc, eloc);
6270 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006271
6272 // Any token we don't specifically annotate will have a NULL cursor.
6273 CXCursor C = clang_getNullCursor();
6274 for (unsigned I = 0; I != NumTokens; ++I)
6275 Cursors[I] = C;
6276
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006277 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006278 if (!CXXUnit)
6279 return;
6280
6281 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006282
6283 auto AnnotateTokensImpl = [=]() {
6284 clang_annotateTokensImpl(TU, CXXUnit, Tokens, NumTokens, Cursors);
6285 };
Guy Benyei11169dd2012-12-18 14:30:41 +00006286 llvm::CrashRecoveryContext CRC;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006287 if (!RunSafely(CRC, AnnotateTokensImpl, GetSafetyThreadStackSize() * 2)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006288 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6289 }
6290}
6291
6292} // end: extern "C"
6293
6294//===----------------------------------------------------------------------===//
6295// Operations for querying linkage of a cursor.
6296//===----------------------------------------------------------------------===//
6297
6298extern "C" {
6299CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6300 if (!clang_isDeclaration(cursor.kind))
6301 return CXLinkage_Invalid;
6302
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006303 const Decl *D = cxcursor::getCursorDecl(cursor);
6304 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006305 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006306 case NoLinkage:
6307 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006308 case InternalLinkage: return CXLinkage_Internal;
6309 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6310 case ExternalLinkage: return CXLinkage_External;
6311 };
6312
6313 return CXLinkage_Invalid;
6314}
6315} // end: extern "C"
6316
6317//===----------------------------------------------------------------------===//
6318// Operations for querying language of a cursor.
6319//===----------------------------------------------------------------------===//
6320
6321static CXLanguageKind getDeclLanguage(const Decl *D) {
6322 if (!D)
6323 return CXLanguage_C;
6324
6325 switch (D->getKind()) {
6326 default:
6327 break;
6328 case Decl::ImplicitParam:
6329 case Decl::ObjCAtDefsField:
6330 case Decl::ObjCCategory:
6331 case Decl::ObjCCategoryImpl:
6332 case Decl::ObjCCompatibleAlias:
6333 case Decl::ObjCImplementation:
6334 case Decl::ObjCInterface:
6335 case Decl::ObjCIvar:
6336 case Decl::ObjCMethod:
6337 case Decl::ObjCProperty:
6338 case Decl::ObjCPropertyImpl:
6339 case Decl::ObjCProtocol:
Douglas Gregor85f3f952015-07-07 03:57:15 +00006340 case Decl::ObjCTypeParam:
Guy Benyei11169dd2012-12-18 14:30:41 +00006341 return CXLanguage_ObjC;
6342 case Decl::CXXConstructor:
6343 case Decl::CXXConversion:
6344 case Decl::CXXDestructor:
6345 case Decl::CXXMethod:
6346 case Decl::CXXRecord:
6347 case Decl::ClassTemplate:
6348 case Decl::ClassTemplatePartialSpecialization:
6349 case Decl::ClassTemplateSpecialization:
6350 case Decl::Friend:
6351 case Decl::FriendTemplate:
6352 case Decl::FunctionTemplate:
6353 case Decl::LinkageSpec:
6354 case Decl::Namespace:
6355 case Decl::NamespaceAlias:
6356 case Decl::NonTypeTemplateParm:
6357 case Decl::StaticAssert:
6358 case Decl::TemplateTemplateParm:
6359 case Decl::TemplateTypeParm:
6360 case Decl::UnresolvedUsingTypename:
6361 case Decl::UnresolvedUsingValue:
6362 case Decl::Using:
6363 case Decl::UsingDirective:
6364 case Decl::UsingShadow:
6365 return CXLanguage_CPlusPlus;
6366 }
6367
6368 return CXLanguage_C;
6369}
6370
6371extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006372
6373static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6374 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
6375 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00006376
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006377 switch (D->getAvailability()) {
6378 case AR_Available:
6379 case AR_NotYetIntroduced:
6380 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006381 return getCursorAvailabilityForDecl(
6382 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006383 return CXAvailability_Available;
6384
6385 case AR_Deprecated:
6386 return CXAvailability_Deprecated;
6387
6388 case AR_Unavailable:
6389 return CXAvailability_NotAvailable;
6390 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006391
6392 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006393}
6394
Guy Benyei11169dd2012-12-18 14:30:41 +00006395enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6396 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006397 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6398 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006399
6400 return CXAvailability_Available;
6401}
6402
6403static CXVersion convertVersion(VersionTuple In) {
6404 CXVersion Out = { -1, -1, -1 };
6405 if (In.empty())
6406 return Out;
6407
6408 Out.Major = In.getMajor();
6409
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006410 Optional<unsigned> Minor = In.getMinor();
6411 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006412 Out.Minor = *Minor;
6413 else
6414 return Out;
6415
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006416 Optional<unsigned> Subminor = In.getSubminor();
6417 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006418 Out.Subminor = *Subminor;
6419
6420 return Out;
6421}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006422
6423static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6424 int *always_deprecated,
6425 CXString *deprecated_message,
6426 int *always_unavailable,
6427 CXString *unavailable_message,
6428 CXPlatformAvailability *availability,
6429 int availability_size) {
6430 bool HadAvailAttr = false;
6431 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006432 for (auto A : D->attrs()) {
6433 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006434 HadAvailAttr = true;
6435 if (always_deprecated)
6436 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006437 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006438 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006439 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006440 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006441 continue;
6442 }
6443
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006444 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006445 HadAvailAttr = true;
6446 if (always_unavailable)
6447 *always_unavailable = 1;
6448 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006449 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006450 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6451 }
6452 continue;
6453 }
6454
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006455 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006456 HadAvailAttr = true;
6457 if (N < availability_size) {
6458 availability[N].Platform
6459 = cxstring::createDup(Avail->getPlatform()->getName());
6460 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6461 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6462 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6463 availability[N].Unavailable = Avail->getUnavailable();
6464 availability[N].Message = cxstring::createDup(Avail->getMessage());
6465 }
6466 ++N;
6467 }
6468 }
6469
6470 if (!HadAvailAttr)
6471 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6472 return getCursorPlatformAvailabilityForDecl(
6473 cast<Decl>(EnumConst->getDeclContext()),
6474 always_deprecated,
6475 deprecated_message,
6476 always_unavailable,
6477 unavailable_message,
6478 availability,
6479 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006480
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006481 return N;
6482}
6483
Guy Benyei11169dd2012-12-18 14:30:41 +00006484int clang_getCursorPlatformAvailability(CXCursor cursor,
6485 int *always_deprecated,
6486 CXString *deprecated_message,
6487 int *always_unavailable,
6488 CXString *unavailable_message,
6489 CXPlatformAvailability *availability,
6490 int availability_size) {
6491 if (always_deprecated)
6492 *always_deprecated = 0;
6493 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006494 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006495 if (always_unavailable)
6496 *always_unavailable = 0;
6497 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006498 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006499
Guy Benyei11169dd2012-12-18 14:30:41 +00006500 if (!clang_isDeclaration(cursor.kind))
6501 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006502
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006503 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006504 if (!D)
6505 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006506
6507 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6508 deprecated_message,
6509 always_unavailable,
6510 unavailable_message,
6511 availability,
6512 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006513}
6514
6515void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6516 clang_disposeString(availability->Platform);
6517 clang_disposeString(availability->Message);
6518}
6519
6520CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6521 if (clang_isDeclaration(cursor.kind))
6522 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6523
6524 return CXLanguage_Invalid;
6525}
6526
6527 /// \brief If the given cursor is the "templated" declaration
6528 /// descibing a class or function template, return the class or
6529 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006530static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006531 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006532 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006533
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006534 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006535 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6536 return FunTmpl;
6537
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006538 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006539 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6540 return ClassTmpl;
6541
6542 return D;
6543}
6544
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006545
6546enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
6547 StorageClass sc = SC_None;
6548 const Decl *D = getCursorDecl(C);
6549 if (D) {
6550 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
6551 sc = FD->getStorageClass();
6552 } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
6553 sc = VD->getStorageClass();
6554 } else {
6555 return CX_SC_Invalid;
6556 }
6557 } else {
6558 return CX_SC_Invalid;
6559 }
6560 switch (sc) {
6561 case SC_None:
6562 return CX_SC_None;
6563 case SC_Extern:
6564 return CX_SC_Extern;
6565 case SC_Static:
6566 return CX_SC_Static;
6567 case SC_PrivateExtern:
6568 return CX_SC_PrivateExtern;
6569 case SC_OpenCLWorkGroupLocal:
6570 return CX_SC_OpenCLWorkGroupLocal;
6571 case SC_Auto:
6572 return CX_SC_Auto;
6573 case SC_Register:
6574 return CX_SC_Register;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006575 }
Kaelyn Takataab61e702014-10-15 18:03:26 +00006576 llvm_unreachable("Unhandled storage class!");
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006577}
6578
Guy Benyei11169dd2012-12-18 14:30:41 +00006579CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6580 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006581 if (const Decl *D = getCursorDecl(cursor)) {
6582 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006583 if (!DC)
6584 return clang_getNullCursor();
6585
6586 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6587 getCursorTU(cursor));
6588 }
6589 }
6590
6591 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006592 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006593 return MakeCXCursor(D, getCursorTU(cursor));
6594 }
6595
6596 return clang_getNullCursor();
6597}
6598
6599CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6600 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006601 if (const Decl *D = getCursorDecl(cursor)) {
6602 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006603 if (!DC)
6604 return clang_getNullCursor();
6605
6606 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6607 getCursorTU(cursor));
6608 }
6609 }
6610
6611 // FIXME: Note that we can't easily compute the lexical context of a
6612 // statement or expression, so we return nothing.
6613 return clang_getNullCursor();
6614}
6615
6616CXFile clang_getIncludedFile(CXCursor cursor) {
6617 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006618 return nullptr;
6619
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006620 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006621 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006622}
6623
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006624unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6625 if (C.kind != CXCursor_ObjCPropertyDecl)
6626 return CXObjCPropertyAttr_noattr;
6627
6628 unsigned Result = CXObjCPropertyAttr_noattr;
6629 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6630 ObjCPropertyDecl::PropertyAttributeKind Attr =
6631 PD->getPropertyAttributesAsWritten();
6632
6633#define SET_CXOBJCPROP_ATTR(A) \
6634 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6635 Result |= CXObjCPropertyAttr_##A
6636 SET_CXOBJCPROP_ATTR(readonly);
6637 SET_CXOBJCPROP_ATTR(getter);
6638 SET_CXOBJCPROP_ATTR(assign);
6639 SET_CXOBJCPROP_ATTR(readwrite);
6640 SET_CXOBJCPROP_ATTR(retain);
6641 SET_CXOBJCPROP_ATTR(copy);
6642 SET_CXOBJCPROP_ATTR(nonatomic);
6643 SET_CXOBJCPROP_ATTR(setter);
6644 SET_CXOBJCPROP_ATTR(atomic);
6645 SET_CXOBJCPROP_ATTR(weak);
6646 SET_CXOBJCPROP_ATTR(strong);
6647 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6648#undef SET_CXOBJCPROP_ATTR
6649
6650 return Result;
6651}
6652
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006653unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6654 if (!clang_isDeclaration(C.kind))
6655 return CXObjCDeclQualifier_None;
6656
6657 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6658 const Decl *D = getCursorDecl(C);
6659 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6660 QT = MD->getObjCDeclQualifier();
6661 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6662 QT = PD->getObjCDeclQualifier();
6663 if (QT == Decl::OBJC_TQ_None)
6664 return CXObjCDeclQualifier_None;
6665
6666 unsigned Result = CXObjCDeclQualifier_None;
6667 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6668 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6669 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6670 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6671 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6672 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6673
6674 return Result;
6675}
6676
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006677unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6678 if (!clang_isDeclaration(C.kind))
6679 return 0;
6680
6681 const Decl *D = getCursorDecl(C);
6682 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6683 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6684 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6685 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6686
6687 return 0;
6688}
6689
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006690unsigned clang_Cursor_isVariadic(CXCursor C) {
6691 if (!clang_isDeclaration(C.kind))
6692 return 0;
6693
6694 const Decl *D = getCursorDecl(C);
6695 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6696 return FD->isVariadic();
6697 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6698 return MD->isVariadic();
6699
6700 return 0;
6701}
6702
Guy Benyei11169dd2012-12-18 14:30:41 +00006703CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6704 if (!clang_isDeclaration(C.kind))
6705 return clang_getNullRange();
6706
6707 const Decl *D = getCursorDecl(C);
6708 ASTContext &Context = getCursorContext(C);
6709 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6710 if (!RC)
6711 return clang_getNullRange();
6712
6713 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6714}
6715
6716CXString clang_Cursor_getRawCommentText(CXCursor C) {
6717 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006718 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006719
6720 const Decl *D = getCursorDecl(C);
6721 ASTContext &Context = getCursorContext(C);
6722 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6723 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6724 StringRef();
6725
6726 // Don't duplicate the string because RawText points directly into source
6727 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006728 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006729}
6730
6731CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6732 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006733 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006734
6735 const Decl *D = getCursorDecl(C);
6736 const ASTContext &Context = getCursorContext(C);
6737 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6738
6739 if (RC) {
6740 StringRef BriefText = RC->getBriefText(Context);
6741
6742 // Don't duplicate the string because RawComment ensures that this memory
6743 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006744 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006745 }
6746
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006747 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006748}
6749
Guy Benyei11169dd2012-12-18 14:30:41 +00006750CXModule clang_Cursor_getModule(CXCursor C) {
6751 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006752 if (const ImportDecl *ImportD =
6753 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006754 return ImportD->getImportedModule();
6755 }
6756
Craig Topper69186e72014-06-08 08:38:04 +00006757 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006758}
6759
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006760CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6761 if (isNotUsableTU(TU)) {
6762 LOG_BAD_TU(TU);
6763 return nullptr;
6764 }
6765 if (!File)
6766 return nullptr;
6767 FileEntry *FE = static_cast<FileEntry *>(File);
6768
6769 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6770 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6771 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6772
Richard Smithfeb54b62014-10-23 02:01:19 +00006773 return Header.getModule();
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006774}
6775
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006776CXFile clang_Module_getASTFile(CXModule CXMod) {
6777 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006778 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006779 Module *Mod = static_cast<Module*>(CXMod);
6780 return const_cast<FileEntry *>(Mod->getASTFile());
6781}
6782
Guy Benyei11169dd2012-12-18 14:30:41 +00006783CXModule clang_Module_getParent(CXModule CXMod) {
6784 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006785 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006786 Module *Mod = static_cast<Module*>(CXMod);
6787 return Mod->Parent;
6788}
6789
6790CXString clang_Module_getName(CXModule CXMod) {
6791 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006792 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006793 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006794 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006795}
6796
6797CXString clang_Module_getFullName(CXModule CXMod) {
6798 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006799 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006800 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006801 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006802}
6803
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006804int clang_Module_isSystem(CXModule CXMod) {
6805 if (!CXMod)
6806 return 0;
6807 Module *Mod = static_cast<Module*>(CXMod);
6808 return Mod->IsSystem;
6809}
6810
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006811unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6812 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006813 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006814 LOG_BAD_TU(TU);
6815 return 0;
6816 }
6817 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006818 return 0;
6819 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006820 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6821 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6822 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006823}
6824
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006825CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6826 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006827 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006828 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006829 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006830 }
6831 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006832 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006833 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006834 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006835
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006836 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6837 if (Index < TopHeaders.size())
6838 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006839
Craig Topper69186e72014-06-08 08:38:04 +00006840 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006841}
6842
6843} // end: extern "C"
6844
6845//===----------------------------------------------------------------------===//
6846// C++ AST instrospection.
6847//===----------------------------------------------------------------------===//
6848
6849extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006850unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6851 if (!clang_isDeclaration(C.kind))
6852 return 0;
6853
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006854 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006855 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006856 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006857 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6858}
6859
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006860unsigned clang_CXXMethod_isConst(CXCursor C) {
6861 if (!clang_isDeclaration(C.kind))
6862 return 0;
6863
6864 const Decl *D = cxcursor::getCursorDecl(C);
6865 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006866 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006867 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6868}
6869
Guy Benyei11169dd2012-12-18 14:30:41 +00006870unsigned clang_CXXMethod_isStatic(CXCursor C) {
6871 if (!clang_isDeclaration(C.kind))
6872 return 0;
6873
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006874 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006875 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006876 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006877 return (Method && Method->isStatic()) ? 1 : 0;
6878}
6879
6880unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6881 if (!clang_isDeclaration(C.kind))
6882 return 0;
6883
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006884 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006885 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006886 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006887 return (Method && Method->isVirtual()) ? 1 : 0;
6888}
6889} // end: extern "C"
6890
6891//===----------------------------------------------------------------------===//
6892// Attribute introspection.
6893//===----------------------------------------------------------------------===//
6894
6895extern "C" {
6896CXType clang_getIBOutletCollectionType(CXCursor C) {
6897 if (C.kind != CXCursor_IBOutletCollectionAttr)
6898 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6899
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006900 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006901 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6902
6903 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6904}
6905} // end: extern "C"
6906
6907//===----------------------------------------------------------------------===//
6908// Inspecting memory usage.
6909//===----------------------------------------------------------------------===//
6910
6911typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6912
6913static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6914 enum CXTUResourceUsageKind k,
6915 unsigned long amount) {
6916 CXTUResourceUsageEntry entry = { k, amount };
6917 entries.push_back(entry);
6918}
6919
6920extern "C" {
6921
6922const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6923 const char *str = "";
6924 switch (kind) {
6925 case CXTUResourceUsage_AST:
6926 str = "ASTContext: expressions, declarations, and types";
6927 break;
6928 case CXTUResourceUsage_Identifiers:
6929 str = "ASTContext: identifiers";
6930 break;
6931 case CXTUResourceUsage_Selectors:
6932 str = "ASTContext: selectors";
6933 break;
6934 case CXTUResourceUsage_GlobalCompletionResults:
6935 str = "Code completion: cached global results";
6936 break;
6937 case CXTUResourceUsage_SourceManagerContentCache:
6938 str = "SourceManager: content cache allocator";
6939 break;
6940 case CXTUResourceUsage_AST_SideTables:
6941 str = "ASTContext: side tables";
6942 break;
6943 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6944 str = "SourceManager: malloc'ed memory buffers";
6945 break;
6946 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6947 str = "SourceManager: mmap'ed memory buffers";
6948 break;
6949 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6950 str = "ExternalASTSource: malloc'ed memory buffers";
6951 break;
6952 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6953 str = "ExternalASTSource: mmap'ed memory buffers";
6954 break;
6955 case CXTUResourceUsage_Preprocessor:
6956 str = "Preprocessor: malloc'ed memory";
6957 break;
6958 case CXTUResourceUsage_PreprocessingRecord:
6959 str = "Preprocessor: PreprocessingRecord";
6960 break;
6961 case CXTUResourceUsage_SourceManager_DataStructures:
6962 str = "SourceManager: data structures and tables";
6963 break;
6964 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6965 str = "Preprocessor: header search tables";
6966 break;
6967 }
6968 return str;
6969}
6970
6971CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006972 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006973 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006974 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00006975 return usage;
6976 }
6977
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006978 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006979 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006980 ASTContext &astContext = astUnit->getASTContext();
6981
6982 // How much memory is used by AST nodes and types?
6983 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6984 (unsigned long) astContext.getASTAllocatedMemory());
6985
6986 // How much memory is used by identifiers?
6987 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6988 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6989
6990 // How much memory is used for selectors?
6991 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6992 (unsigned long) astContext.Selectors.getTotalMemory());
6993
6994 // How much memory is used by ASTContext's side tables?
6995 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6996 (unsigned long) astContext.getSideTableAllocatedMemory());
6997
6998 // How much memory is used for caching global code completion results?
6999 unsigned long completionBytes = 0;
7000 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00007001 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007002 completionBytes = completionAllocator->getTotalMemory();
7003 }
7004 createCXTUResourceUsageEntry(*entries,
7005 CXTUResourceUsage_GlobalCompletionResults,
7006 completionBytes);
7007
7008 // How much memory is being used by SourceManager's content cache?
7009 createCXTUResourceUsageEntry(*entries,
7010 CXTUResourceUsage_SourceManagerContentCache,
7011 (unsigned long) astContext.getSourceManager().getContentCacheSize());
7012
7013 // How much memory is being used by the MemoryBuffer's in SourceManager?
7014 const SourceManager::MemoryBufferSizes &srcBufs =
7015 astUnit->getSourceManager().getMemoryBufferSizes();
7016
7017 createCXTUResourceUsageEntry(*entries,
7018 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
7019 (unsigned long) srcBufs.malloc_bytes);
7020 createCXTUResourceUsageEntry(*entries,
7021 CXTUResourceUsage_SourceManager_Membuffer_MMap,
7022 (unsigned long) srcBufs.mmap_bytes);
7023 createCXTUResourceUsageEntry(*entries,
7024 CXTUResourceUsage_SourceManager_DataStructures,
7025 (unsigned long) astContext.getSourceManager()
7026 .getDataStructureSizes());
7027
7028 // How much memory is being used by the ExternalASTSource?
7029 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
7030 const ExternalASTSource::MemoryBufferSizes &sizes =
7031 esrc->getMemoryBufferSizes();
7032
7033 createCXTUResourceUsageEntry(*entries,
7034 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
7035 (unsigned long) sizes.malloc_bytes);
7036 createCXTUResourceUsageEntry(*entries,
7037 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
7038 (unsigned long) sizes.mmap_bytes);
7039 }
7040
7041 // How much memory is being used by the Preprocessor?
7042 Preprocessor &pp = astUnit->getPreprocessor();
7043 createCXTUResourceUsageEntry(*entries,
7044 CXTUResourceUsage_Preprocessor,
7045 pp.getTotalMemory());
7046
7047 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
7048 createCXTUResourceUsageEntry(*entries,
7049 CXTUResourceUsage_PreprocessingRecord,
7050 pRec->getTotalMemory());
7051 }
7052
7053 createCXTUResourceUsageEntry(*entries,
7054 CXTUResourceUsage_Preprocessor_HeaderSearch,
7055 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00007056
Guy Benyei11169dd2012-12-18 14:30:41 +00007057 CXTUResourceUsage usage = { (void*) entries.get(),
7058 (unsigned) entries->size(),
Alexander Kornienko6ee521c2015-01-23 15:36:10 +00007059 !entries->empty() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00007060 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00007061 return usage;
7062}
7063
7064void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
7065 if (usage.data)
7066 delete (MemUsageEntries*) usage.data;
7067}
7068
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007069CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
7070 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007071 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00007072 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007073
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007074 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007075 LOG_BAD_TU(TU);
7076 return skipped;
7077 }
7078
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007079 if (!file)
7080 return skipped;
7081
7082 ASTUnit *astUnit = cxtu::getASTUnit(TU);
7083 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
7084 if (!ppRec)
7085 return skipped;
7086
7087 ASTContext &Ctx = astUnit->getASTContext();
7088 SourceManager &sm = Ctx.getSourceManager();
7089 FileEntry *fileEntry = static_cast<FileEntry *>(file);
7090 FileID wantedFileID = sm.translateFile(fileEntry);
7091
7092 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
7093 std::vector<SourceRange> wantedRanges;
7094 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
7095 i != ei; ++i) {
7096 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
7097 wantedRanges.push_back(*i);
7098 }
7099
7100 skipped->count = wantedRanges.size();
7101 skipped->ranges = new CXSourceRange[skipped->count];
7102 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
7103 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
7104
7105 return skipped;
7106}
7107
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007108void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
7109 if (ranges) {
7110 delete[] ranges->ranges;
7111 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007112 }
7113}
7114
Guy Benyei11169dd2012-12-18 14:30:41 +00007115} // end extern "C"
7116
7117void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
7118 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
7119 for (unsigned I = 0; I != Usage.numEntries; ++I)
7120 fprintf(stderr, " %s: %lu\n",
7121 clang_getTUResourceUsageName(Usage.entries[I].kind),
7122 Usage.entries[I].amount);
7123
7124 clang_disposeCXTUResourceUsage(Usage);
7125}
7126
7127//===----------------------------------------------------------------------===//
7128// Misc. utility functions.
7129//===----------------------------------------------------------------------===//
7130
7131/// Default to using an 8 MB stack size on "safety" threads.
7132static unsigned SafetyStackThreadSize = 8 << 20;
7133
7134namespace clang {
7135
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007136bool RunSafely(llvm::CrashRecoveryContext &CRC, llvm::function_ref<void()> Fn,
Guy Benyei11169dd2012-12-18 14:30:41 +00007137 unsigned Size) {
7138 if (!Size)
7139 Size = GetSafetyThreadStackSize();
7140 if (Size)
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007141 return CRC.RunSafelyOnThread(Fn, Size);
7142 return CRC.RunSafely(Fn);
Guy Benyei11169dd2012-12-18 14:30:41 +00007143}
7144
7145unsigned GetSafetyThreadStackSize() {
7146 return SafetyStackThreadSize;
7147}
7148
7149void SetSafetyThreadStackSize(unsigned Value) {
7150 SafetyStackThreadSize = Value;
7151}
7152
Alexander Kornienkoab9db512015-06-22 23:07:51 +00007153}
Guy Benyei11169dd2012-12-18 14:30:41 +00007154
7155void clang::setThreadBackgroundPriority() {
7156 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
7157 return;
7158
Alp Toker1a86ad22014-07-06 06:24:00 +00007159#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00007160 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
7161#endif
7162}
7163
7164void cxindex::printDiagsToStderr(ASTUnit *Unit) {
7165 if (!Unit)
7166 return;
7167
7168 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
7169 DEnd = Unit->stored_diag_end();
7170 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00007171 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00007172 CXString Msg = clang_formatDiagnostic(&Diag,
7173 clang_defaultDiagnosticDisplayOptions());
7174 fprintf(stderr, "%s\n", clang_getCString(Msg));
7175 clang_disposeString(Msg);
7176 }
7177#ifdef LLVM_ON_WIN32
7178 // On Windows, force a flush, since there may be multiple copies of
7179 // stderr and stdout in the file system, all with different buffers
7180 // but writing to the same device.
7181 fflush(stderr);
7182#endif
7183}
7184
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007185MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
7186 SourceLocation MacroDefLoc,
7187 CXTranslationUnit TU){
7188 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007189 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007190 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007191 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007192
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007193 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007194 Preprocessor &PP = Unit->getPreprocessor();
Richard Smith20e883e2015-04-29 23:20:19 +00007195 MacroDirective *MD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007196 if (MD) {
7197 for (MacroDirective::DefInfo
7198 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
7199 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
7200 return Def.getMacroInfo();
7201 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007202 }
7203
Craig Topper69186e72014-06-08 08:38:04 +00007204 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007205}
7206
Richard Smith66a81862015-05-04 02:25:31 +00007207const MacroInfo *cxindex::getMacroInfo(const MacroDefinitionRecord *MacroDef,
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007208 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007209 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007210 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007211 const IdentifierInfo *II = MacroDef->getName();
7212 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00007213 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007214
7215 return getMacroInfo(*II, MacroDef->getLocation(), TU);
7216}
7217
Richard Smith66a81862015-05-04 02:25:31 +00007218MacroDefinitionRecord *
7219cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, const Token &Tok,
7220 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007221 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007222 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007223 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00007224 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007225
7226 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007227 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007228 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
7229 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007230 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007231
7232 // Check that the token is inside the definition and not its argument list.
7233 SourceManager &SM = Unit->getSourceManager();
7234 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00007235 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007236 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00007237 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007238
7239 Preprocessor &PP = Unit->getPreprocessor();
7240 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
7241 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00007242 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007243
Alp Toker2d57cea2014-05-17 04:53:25 +00007244 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
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
7248 // Check that the identifier is not one of the macro arguments.
7249 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00007250 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007251
Richard Smith20e883e2015-04-29 23:20:19 +00007252 MacroDirective *InnerMD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007253 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00007254 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007255
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007256 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007257}
7258
Richard Smith66a81862015-05-04 02:25:31 +00007259MacroDefinitionRecord *
7260cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, SourceLocation Loc,
7261 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007262 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007263 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007264
7265 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007266 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007267 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007268 Preprocessor &PP = Unit->getPreprocessor();
7269 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00007270 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007271 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7272 Token Tok;
7273 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00007274 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007275
7276 return checkForMacroInMacroDefinition(MI, Tok, TU);
7277}
7278
Guy Benyei11169dd2012-12-18 14:30:41 +00007279extern "C" {
7280
7281CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007282 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00007283}
7284
7285} // end: extern "C"
7286
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007287Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7288 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007289 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007290 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007291 if (Unit->isMainFileAST())
7292 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007293 return *this;
7294 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007295 } else {
7296 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007297 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007298 return *this;
7299}
7300
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007301Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7302 *this << FE->getName();
7303 return *this;
7304}
7305
7306Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7307 CXString cursorName = clang_getCursorDisplayName(cursor);
7308 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7309 clang_disposeString(cursorName);
7310 return *this;
7311}
7312
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007313Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7314 CXFile File;
7315 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007316 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007317 CXString FileName = clang_getFileName(File);
7318 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7319 clang_disposeString(FileName);
7320 return *this;
7321}
7322
7323Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7324 CXSourceLocation BLoc = clang_getRangeStart(range);
7325 CXSourceLocation ELoc = clang_getRangeEnd(range);
7326
7327 CXFile BFile;
7328 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007329 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007330
7331 CXFile EFile;
7332 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007333 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007334
7335 CXString BFileName = clang_getFileName(BFile);
7336 if (BFile == EFile) {
7337 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7338 BLine, BColumn, ELine, EColumn);
7339 } else {
7340 CXString EFileName = clang_getFileName(EFile);
7341 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7342 BLine, BColumn)
7343 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7344 ELine, EColumn);
7345 clang_disposeString(EFileName);
7346 }
7347 clang_disposeString(BFileName);
7348 return *this;
7349}
7350
7351Logger &cxindex::Logger::operator<<(CXString Str) {
7352 *this << clang_getCString(Str);
7353 return *this;
7354}
7355
7356Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7357 LogOS << Fmt;
7358 return *this;
7359}
7360
Chandler Carruth37ad2582014-06-27 15:14:39 +00007361static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7362
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007363cxindex::Logger::~Logger() {
7364 LogOS.flush();
7365
Chandler Carruth37ad2582014-06-27 15:14:39 +00007366 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007367
7368 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7369
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007370 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007371 OS << "[libclang:" << Name << ':';
7372
Alp Toker1a86ad22014-07-06 06:24:00 +00007373#ifdef USE_DARWIN_THREADS
7374 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007375 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7376 OS << tid << ':';
7377#endif
7378
7379 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7380 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
Yaron Keren09fb7c62015-03-10 07:33:23 +00007381 OS << Msg << '\n';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007382
7383 if (Trace) {
Zachary Turner1fe2a8d2015-03-05 19:15:09 +00007384 llvm::sys::PrintStackTrace(OS);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007385 OS << "--------------------------------------------------\n";
7386 }
7387}