blob: 6e48bab9f509be77be270c3c8b338c203058d0b8 [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);
Alexey Bataev13314bf2014-10-09 04:18:56 +00001933 void VisitOMPTeamsDirective(const OMPTeamsDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001934
Guy Benyei11169dd2012-12-18 14:30:41 +00001935private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001936 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001937 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1938 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001939 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1940 void AddStmt(const Stmt *S);
1941 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001942 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001943 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001944 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001945};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00001946} // end anonyous namespace
Guy Benyei11169dd2012-12-18 14:30:41 +00001947
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001948void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001949 // 'S' should always be non-null, since it comes from the
1950 // statement we are visiting.
1951 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1952}
1953
1954void
1955EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1956 if (Qualifier)
1957 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1958}
1959
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001960void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001961 if (S)
1962 WL.push_back(StmtVisit(S, Parent));
1963}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001964void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001965 if (D)
1966 WL.push_back(DeclVisit(D, Parent, isFirst));
1967}
1968void EnqueueVisitor::
1969 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1970 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001971 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001972}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001973void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001974 if (D)
1975 WL.push_back(MemberRefVisit(D, L, Parent));
1976}
1977void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1978 if (TI)
1979 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1980 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001981void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001982 unsigned size = WL.size();
Benjamin Kramer642f1732015-07-02 21:03:14 +00001983 for (const Stmt *SubStmt : S->children()) {
1984 AddStmt(SubStmt);
Guy Benyei11169dd2012-12-18 14:30:41 +00001985 }
1986 if (size == WL.size())
1987 return;
1988 // Now reverse the entries we just added. This will match the DFS
1989 // ordering performed by the worklist.
1990 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1991 std::reverse(I, E);
1992}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001993namespace {
1994class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1995 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001996 /// \brief Process clauses with list of variables.
1997 template <typename T>
1998 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001999public:
2000 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
2001#define OPENMP_CLAUSE(Name, Class) \
2002 void Visit##Class(const Class *C);
2003#include "clang/Basic/OpenMPKinds.def"
2004};
2005
Alexey Bataevaadd52e2014-02-13 05:29:23 +00002006void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
2007 Visitor->AddStmt(C->getCondition());
2008}
2009
Alexey Bataev3778b602014-07-17 07:32:53 +00002010void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
2011 Visitor->AddStmt(C->getCondition());
2012}
2013
Alexey Bataev568a8332014-03-06 06:15:19 +00002014void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
2015 Visitor->AddStmt(C->getNumThreads());
2016}
2017
Alexey Bataev62c87d22014-03-21 04:51:18 +00002018void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
2019 Visitor->AddStmt(C->getSafelen());
2020}
2021
Alexander Musman8bd31e62014-05-27 15:12:19 +00002022void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
2023 Visitor->AddStmt(C->getNumForLoops());
2024}
2025
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002026void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00002027
Alexey Bataevbcbadb62014-05-06 06:04:14 +00002028void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
2029
Alexey Bataev56dafe82014-06-20 07:16:17 +00002030void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
2031 Visitor->AddStmt(C->getChunkSize());
Alexey Bataev040d5402015-05-12 08:35:28 +00002032 Visitor->AddStmt(C->getHelperChunkSize());
Alexey Bataev56dafe82014-06-20 07:16:17 +00002033}
2034
Alexey Bataev142e1fc2014-06-20 09:44:06 +00002035void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *) {}
2036
Alexey Bataev236070f2014-06-20 11:19:47 +00002037void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
2038
Alexey Bataev7aea99a2014-07-17 12:19:31 +00002039void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
2040
Alexey Bataev74ba3a52014-07-17 12:47:03 +00002041void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
2042
Alexey Bataevf98b00c2014-07-23 02:27:21 +00002043void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}
2044
Alexey Bataevdea47612014-07-23 07:46:59 +00002045void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {}
2046
Alexey Bataev67a4f222014-07-23 10:25:33 +00002047void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {}
2048
Alexey Bataev459dec02014-07-24 06:46:57 +00002049void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}
2050
Alexey Bataev82bad8b2014-07-24 08:55:34 +00002051void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
2052
Alexey Bataev756c1962013-09-24 03:17:45 +00002053template<typename T>
2054void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Alexey Bataev03b340a2014-10-21 03:16:40 +00002055 for (const auto *I : Node->varlists()) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00002056 Visitor->AddStmt(I);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002057 }
Alexey Bataev756c1962013-09-24 03:17:45 +00002058}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002059
2060void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002061 VisitOMPClauseList(C);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002062 for (const auto *E : C->private_copies()) {
2063 Visitor->AddStmt(E);
2064 }
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002065}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002066void OMPClauseEnqueue::VisitOMPFirstprivateClause(
2067 const OMPFirstprivateClause *C) {
2068 VisitOMPClauseList(C);
2069}
Alexander Musman1bb328c2014-06-04 13:06:39 +00002070void OMPClauseEnqueue::VisitOMPLastprivateClause(
2071 const OMPLastprivateClause *C) {
2072 VisitOMPClauseList(C);
Alexey Bataev38e89532015-04-16 04:54:05 +00002073 for (auto *E : C->private_copies()) {
2074 Visitor->AddStmt(E);
2075 }
2076 for (auto *E : C->source_exprs()) {
2077 Visitor->AddStmt(E);
2078 }
2079 for (auto *E : C->destination_exprs()) {
2080 Visitor->AddStmt(E);
2081 }
2082 for (auto *E : C->assignment_ops()) {
2083 Visitor->AddStmt(E);
2084 }
Alexander Musman1bb328c2014-06-04 13:06:39 +00002085}
Alexey Bataev758e55e2013-09-06 18:03:48 +00002086void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002087 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00002088}
Alexey Bataevc5e02582014-06-16 07:08:35 +00002089void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
2090 VisitOMPClauseList(C);
Alexey Bataev794ba0d2015-04-10 10:43:45 +00002091 for (auto *E : C->lhs_exprs()) {
2092 Visitor->AddStmt(E);
2093 }
2094 for (auto *E : C->rhs_exprs()) {
2095 Visitor->AddStmt(E);
2096 }
2097 for (auto *E : C->reduction_ops()) {
2098 Visitor->AddStmt(E);
2099 }
Alexey Bataevc5e02582014-06-16 07:08:35 +00002100}
Alexander Musman8dba6642014-04-22 13:09:42 +00002101void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2102 VisitOMPClauseList(C);
Alexander Musman3276a272015-03-21 10:12:56 +00002103 for (const auto *E : C->inits()) {
2104 Visitor->AddStmt(E);
2105 }
2106 for (const auto *E : C->updates()) {
2107 Visitor->AddStmt(E);
2108 }
2109 for (const auto *E : C->finals()) {
2110 Visitor->AddStmt(E);
2111 }
Alexander Musman8dba6642014-04-22 13:09:42 +00002112 Visitor->AddStmt(C->getStep());
Alexander Musman3276a272015-03-21 10:12:56 +00002113 Visitor->AddStmt(C->getCalcStep());
Alexander Musman8dba6642014-04-22 13:09:42 +00002114}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002115void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2116 VisitOMPClauseList(C);
2117 Visitor->AddStmt(C->getAlignment());
2118}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002119void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2120 VisitOMPClauseList(C);
Alexey Bataevf56f98c2015-04-16 05:39:01 +00002121 for (auto *E : C->source_exprs()) {
2122 Visitor->AddStmt(E);
2123 }
2124 for (auto *E : C->destination_exprs()) {
2125 Visitor->AddStmt(E);
2126 }
2127 for (auto *E : C->assignment_ops()) {
2128 Visitor->AddStmt(E);
2129 }
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002130}
Alexey Bataevbae9a792014-06-27 10:37:06 +00002131void
2132OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
2133 VisitOMPClauseList(C);
Alexey Bataeva63048e2015-03-23 06:18:07 +00002134 for (auto *E : C->source_exprs()) {
2135 Visitor->AddStmt(E);
2136 }
2137 for (auto *E : C->destination_exprs()) {
2138 Visitor->AddStmt(E);
2139 }
2140 for (auto *E : C->assignment_ops()) {
2141 Visitor->AddStmt(E);
2142 }
Alexey Bataevbae9a792014-06-27 10:37:06 +00002143}
Alexey Bataev6125da92014-07-21 11:26:11 +00002144void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2145 VisitOMPClauseList(C);
2146}
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +00002147void OMPClauseEnqueue::VisitOMPDependClause(const OMPDependClause *C) {
2148 VisitOMPClauseList(C);
2149}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002150}
Alexey Bataev756c1962013-09-24 03:17:45 +00002151
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002152void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2153 unsigned size = WL.size();
2154 OMPClauseEnqueue Visitor(this);
2155 Visitor.Visit(S);
2156 if (size == WL.size())
2157 return;
2158 // Now reverse the entries we just added. This will match the DFS
2159 // ordering performed by the worklist.
2160 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2161 std::reverse(I, E);
2162}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002163void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002164 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2165}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002166void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002167 AddDecl(B->getBlockDecl());
2168}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002169void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002170 EnqueueChildren(E);
2171 AddTypeLoc(E->getTypeSourceInfo());
2172}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002173void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
2174 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00002175 E = S->body_rend(); I != E; ++I) {
2176 AddStmt(*I);
2177 }
2178}
2179void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002180VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002181 AddStmt(S->getSubStmt());
2182 AddDeclarationNameInfo(S);
2183 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2184 AddNestedNameSpecifierLoc(QualifierLoc);
2185}
2186
2187void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002188VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002189 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2190 AddDeclarationNameInfo(E);
2191 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2192 AddNestedNameSpecifierLoc(QualifierLoc);
2193 if (!E->isImplicitAccess())
2194 AddStmt(E->getBase());
2195}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002196void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002197 // Enqueue the initializer , if any.
2198 AddStmt(E->getInitializer());
2199 // Enqueue the array size, if any.
2200 AddStmt(E->getArraySize());
2201 // Enqueue the allocated type.
2202 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2203 // Enqueue the placement arguments.
2204 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2205 AddStmt(E->getPlacementArg(I-1));
2206}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002207void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002208 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2209 AddStmt(CE->getArg(I-1));
2210 AddStmt(CE->getCallee());
2211 AddStmt(CE->getArg(0));
2212}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002213void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2214 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002215 // Visit the name of the type being destroyed.
2216 AddTypeLoc(E->getDestroyedTypeInfo());
2217 // Visit the scope type that looks disturbingly like the nested-name-specifier
2218 // but isn't.
2219 AddTypeLoc(E->getScopeTypeInfo());
2220 // Visit the nested-name-specifier.
2221 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2222 AddNestedNameSpecifierLoc(QualifierLoc);
2223 // Visit base expression.
2224 AddStmt(E->getBase());
2225}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002226void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2227 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002228 AddTypeLoc(E->getTypeSourceInfo());
2229}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002230void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2231 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002232 EnqueueChildren(E);
2233 AddTypeLoc(E->getTypeSourceInfo());
2234}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002235void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002236 EnqueueChildren(E);
2237 if (E->isTypeOperand())
2238 AddTypeLoc(E->getTypeOperandSourceInfo());
2239}
2240
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002241void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2242 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002243 EnqueueChildren(E);
2244 AddTypeLoc(E->getTypeSourceInfo());
2245}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002246void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002247 EnqueueChildren(E);
2248 if (E->isTypeOperand())
2249 AddTypeLoc(E->getTypeOperandSourceInfo());
2250}
2251
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002252void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002253 EnqueueChildren(S);
2254 AddDecl(S->getExceptionDecl());
2255}
2256
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002257void EnqueueVisitor::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002258 AddStmt(S->getBody());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002259 AddStmt(S->getRangeInit());
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002260 AddDecl(S->getLoopVariable());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002261}
2262
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002263void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002264 if (DR->hasExplicitTemplateArgs()) {
2265 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2266 }
2267 WL.push_back(DeclRefExprParts(DR, Parent));
2268}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002269void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2270 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002271 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2272 AddDeclarationNameInfo(E);
2273 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2274}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002275void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002276 unsigned size = WL.size();
2277 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002278 for (const auto *D : S->decls()) {
2279 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002280 isFirst = false;
2281 }
2282 if (size == WL.size())
2283 return;
2284 // Now reverse the entries we just added. This will match the DFS
2285 // ordering performed by the worklist.
2286 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2287 std::reverse(I, E);
2288}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002289void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002290 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002291 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002292 D = E->designators_rbegin(), DEnd = E->designators_rend();
2293 D != DEnd; ++D) {
2294 if (D->isFieldDesignator()) {
2295 if (FieldDecl *Field = D->getField())
2296 AddMemberRef(Field, D->getFieldLoc());
2297 continue;
2298 }
2299 if (D->isArrayDesignator()) {
2300 AddStmt(E->getArrayIndex(*D));
2301 continue;
2302 }
2303 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2304 AddStmt(E->getArrayRangeEnd(*D));
2305 AddStmt(E->getArrayRangeStart(*D));
2306 }
2307}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002308void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002309 EnqueueChildren(E);
2310 AddTypeLoc(E->getTypeInfoAsWritten());
2311}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002312void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002313 AddStmt(FS->getBody());
2314 AddStmt(FS->getInc());
2315 AddStmt(FS->getCond());
2316 AddDecl(FS->getConditionVariable());
2317 AddStmt(FS->getInit());
2318}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002319void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002320 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2321}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002322void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002323 AddStmt(If->getElse());
2324 AddStmt(If->getThen());
2325 AddStmt(If->getCond());
2326 AddDecl(If->getConditionVariable());
2327}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002328void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002329 // We care about the syntactic form of the initializer list, only.
2330 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2331 IE = Syntactic;
2332 EnqueueChildren(IE);
2333}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002334void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002335 WL.push_back(MemberExprParts(M, Parent));
2336
2337 // If the base of the member access expression is an implicit 'this', don't
2338 // visit it.
2339 // FIXME: If we ever want to show these implicit accesses, this will be
2340 // unfortunate. However, clang_getCursor() relies on this behavior.
Argyrios Kyrtzidis58d0e7a2015-03-13 04:40:07 +00002341 if (M->isImplicitAccess())
2342 return;
2343
2344 // Ignore base anonymous struct/union fields, otherwise they will shadow the
2345 // real field that that we are interested in.
2346 if (auto *SubME = dyn_cast<MemberExpr>(M->getBase())) {
2347 if (auto *FD = dyn_cast_or_null<FieldDecl>(SubME->getMemberDecl())) {
2348 if (FD->isAnonymousStructOrUnion()) {
2349 AddStmt(SubME->getBase());
2350 return;
2351 }
2352 }
2353 }
2354
2355 AddStmt(M->getBase());
Guy Benyei11169dd2012-12-18 14:30:41 +00002356}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002357void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002358 AddTypeLoc(E->getEncodedTypeSourceInfo());
2359}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002360void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002361 EnqueueChildren(M);
2362 AddTypeLoc(M->getClassReceiverTypeInfo());
2363}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002364void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002365 // Visit the components of the offsetof expression.
2366 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2367 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2368 const OffsetOfNode &Node = E->getComponent(I-1);
2369 switch (Node.getKind()) {
2370 case OffsetOfNode::Array:
2371 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2372 break;
2373 case OffsetOfNode::Field:
2374 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2375 break;
2376 case OffsetOfNode::Identifier:
2377 case OffsetOfNode::Base:
2378 continue;
2379 }
2380 }
2381 // Visit the type into which we're computing the offset.
2382 AddTypeLoc(E->getTypeSourceInfo());
2383}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002384void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002385 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2386 WL.push_back(OverloadExprParts(E, Parent));
2387}
2388void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002389 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002390 EnqueueChildren(E);
2391 if (E->isArgumentType())
2392 AddTypeLoc(E->getArgumentTypeInfo());
2393}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002394void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002395 EnqueueChildren(S);
2396}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002397void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002398 AddStmt(S->getBody());
2399 AddStmt(S->getCond());
2400 AddDecl(S->getConditionVariable());
2401}
2402
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002403void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002404 AddStmt(W->getBody());
2405 AddStmt(W->getCond());
2406 AddDecl(W->getConditionVariable());
2407}
2408
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002409void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002410 for (unsigned I = E->getNumArgs(); I > 0; --I)
2411 AddTypeLoc(E->getArg(I-1));
2412}
2413
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002414void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002415 AddTypeLoc(E->getQueriedTypeSourceInfo());
2416}
2417
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002418void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002419 EnqueueChildren(E);
2420}
2421
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002422void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002423 VisitOverloadExpr(U);
2424 if (!U->isImplicitAccess())
2425 AddStmt(U->getBase());
2426}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002427void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002428 AddStmt(E->getSubExpr());
2429 AddTypeLoc(E->getWrittenTypeInfo());
2430}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002431void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002432 WL.push_back(SizeOfPackExprParts(E, Parent));
2433}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002434void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002435 // If the opaque value has a source expression, just transparently
2436 // visit that. This is useful for (e.g.) pseudo-object expressions.
2437 if (Expr *SourceExpr = E->getSourceExpr())
2438 return Visit(SourceExpr);
2439}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002440void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002441 AddStmt(E->getBody());
2442 WL.push_back(LambdaExprParts(E, Parent));
2443}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002444void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002445 // Treat the expression like its syntactic form.
2446 Visit(E->getSyntacticForm());
2447}
2448
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002449void EnqueueVisitor::VisitOMPExecutableDirective(
2450 const OMPExecutableDirective *D) {
2451 EnqueueChildren(D);
2452 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2453 E = D->clauses().end();
2454 I != E; ++I)
2455 EnqueueChildren(*I);
2456}
2457
Alexander Musman3aaab662014-08-19 11:27:13 +00002458void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
2459 VisitOMPExecutableDirective(D);
2460}
2461
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002462void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2463 VisitOMPExecutableDirective(D);
2464}
2465
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002466void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002467 VisitOMPLoopDirective(D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002468}
2469
Alexey Bataevf29276e2014-06-18 04:14:57 +00002470void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002471 VisitOMPLoopDirective(D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002472}
2473
Alexander Musmanf82886e2014-09-18 05:12:34 +00002474void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
2475 VisitOMPLoopDirective(D);
2476}
2477
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002478void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2479 VisitOMPExecutableDirective(D);
2480}
2481
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002482void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2483 VisitOMPExecutableDirective(D);
2484}
2485
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002486void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2487 VisitOMPExecutableDirective(D);
2488}
2489
Alexander Musman80c22892014-07-17 08:54:58 +00002490void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2491 VisitOMPExecutableDirective(D);
2492}
2493
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002494void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2495 VisitOMPExecutableDirective(D);
2496 AddDeclarationNameInfo(D);
2497}
2498
Alexey Bataev4acb8592014-07-07 13:01:15 +00002499void
2500EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002501 VisitOMPLoopDirective(D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002502}
2503
Alexander Musmane4e893b2014-09-23 09:33:00 +00002504void EnqueueVisitor::VisitOMPParallelForSimdDirective(
2505 const OMPParallelForSimdDirective *D) {
2506 VisitOMPLoopDirective(D);
2507}
2508
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002509void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2510 const OMPParallelSectionsDirective *D) {
2511 VisitOMPExecutableDirective(D);
2512}
2513
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002514void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2515 VisitOMPExecutableDirective(D);
2516}
2517
Alexey Bataev68446b72014-07-18 07:47:19 +00002518void
2519EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2520 VisitOMPExecutableDirective(D);
2521}
2522
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002523void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2524 VisitOMPExecutableDirective(D);
2525}
2526
Alexey Bataev2df347a2014-07-18 10:17:07 +00002527void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2528 VisitOMPExecutableDirective(D);
2529}
2530
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002531void EnqueueVisitor::VisitOMPTaskgroupDirective(
2532 const OMPTaskgroupDirective *D) {
2533 VisitOMPExecutableDirective(D);
2534}
2535
Alexey Bataev6125da92014-07-21 11:26:11 +00002536void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2537 VisitOMPExecutableDirective(D);
2538}
2539
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002540void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2541 VisitOMPExecutableDirective(D);
2542}
2543
Alexey Bataev0162e452014-07-22 10:10:35 +00002544void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2545 VisitOMPExecutableDirective(D);
2546}
2547
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002548void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
2549 VisitOMPExecutableDirective(D);
2550}
2551
Alexey Bataev13314bf2014-10-09 04:18:56 +00002552void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {
2553 VisitOMPExecutableDirective(D);
2554}
2555
Alexey Bataev6d4ed052015-07-01 06:57:41 +00002556void EnqueueVisitor::VisitOMPCancellationPointDirective(
2557 const OMPCancellationPointDirective *D) {
2558 VisitOMPExecutableDirective(D);
2559}
2560
Alexey Bataev80909872015-07-02 11:25:17 +00002561void EnqueueVisitor::VisitOMPCancelDirective(const OMPCancelDirective *D) {
2562 VisitOMPExecutableDirective(D);
2563}
2564
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002565void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002566 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2567}
2568
2569bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2570 if (RegionOfInterest.isValid()) {
2571 SourceRange Range = getRawCursorExtent(C);
2572 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2573 return false;
2574 }
2575 return true;
2576}
2577
2578bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2579 while (!WL.empty()) {
2580 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002581 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002582
2583 // Set the Parent field, then back to its old value once we're done.
2584 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2585
2586 switch (LI.getKind()) {
2587 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002588 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002589 if (!D)
2590 continue;
2591
2592 // For now, perform default visitation for Decls.
2593 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2594 cast<DeclVisit>(&LI)->isFirst())))
2595 return true;
2596
2597 continue;
2598 }
2599 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2600 const ASTTemplateArgumentListInfo *ArgList =
2601 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2602 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2603 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2604 Arg != ArgEnd; ++Arg) {
2605 if (VisitTemplateArgumentLoc(*Arg))
2606 return true;
2607 }
2608 continue;
2609 }
2610 case VisitorJob::TypeLocVisitKind: {
2611 // Perform default visitation for TypeLocs.
2612 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2613 return true;
2614 continue;
2615 }
2616 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002617 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002618 if (LabelStmt *stmt = LS->getStmt()) {
2619 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2620 TU))) {
2621 return true;
2622 }
2623 }
2624 continue;
2625 }
2626
2627 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2628 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2629 if (VisitNestedNameSpecifierLoc(V->get()))
2630 return true;
2631 continue;
2632 }
2633
2634 case VisitorJob::DeclarationNameInfoVisitKind: {
2635 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2636 ->get()))
2637 return true;
2638 continue;
2639 }
2640 case VisitorJob::MemberRefVisitKind: {
2641 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2642 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2643 return true;
2644 continue;
2645 }
2646 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002647 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002648 if (!S)
2649 continue;
2650
2651 // Update the current cursor.
2652 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2653 if (!IsInRegionOfInterest(Cursor))
2654 continue;
2655 switch (Visitor(Cursor, Parent, ClientData)) {
2656 case CXChildVisit_Break: return true;
2657 case CXChildVisit_Continue: break;
2658 case CXChildVisit_Recurse:
2659 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002660 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002661 EnqueueWorkList(WL, S);
2662 break;
2663 }
2664 continue;
2665 }
2666 case VisitorJob::MemberExprPartsKind: {
2667 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002668 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002669
2670 // Visit the nested-name-specifier
2671 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2672 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2673 return true;
2674
2675 // Visit the declaration name.
2676 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2677 return true;
2678
2679 // Visit the explicitly-specified template arguments, if any.
2680 if (M->hasExplicitTemplateArgs()) {
2681 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2682 *ArgEnd = Arg + M->getNumTemplateArgs();
2683 Arg != ArgEnd; ++Arg) {
2684 if (VisitTemplateArgumentLoc(*Arg))
2685 return true;
2686 }
2687 }
2688 continue;
2689 }
2690 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002691 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002692 // Visit nested-name-specifier, if present.
2693 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2694 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2695 return true;
2696 // Visit declaration name.
2697 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2698 return true;
2699 continue;
2700 }
2701 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002702 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002703 // Visit the nested-name-specifier.
2704 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2705 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2706 return true;
2707 // Visit the declaration name.
2708 if (VisitDeclarationNameInfo(O->getNameInfo()))
2709 return true;
2710 // Visit the overloaded declaration reference.
2711 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2712 return true;
2713 continue;
2714 }
2715 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002716 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002717 NamedDecl *Pack = E->getPack();
2718 if (isa<TemplateTypeParmDecl>(Pack)) {
2719 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2720 E->getPackLoc(), TU)))
2721 return true;
2722
2723 continue;
2724 }
2725
2726 if (isa<TemplateTemplateParmDecl>(Pack)) {
2727 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2728 E->getPackLoc(), TU)))
2729 return true;
2730
2731 continue;
2732 }
2733
2734 // Non-type template parameter packs and function parameter packs are
2735 // treated like DeclRefExpr cursors.
2736 continue;
2737 }
2738
2739 case VisitorJob::LambdaExprPartsKind: {
2740 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002741 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002742 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2743 CEnd = E->explicit_capture_end();
2744 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002745 // FIXME: Lambda init-captures.
2746 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002747 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002748
Guy Benyei11169dd2012-12-18 14:30:41 +00002749 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2750 C->getLocation(),
2751 TU)))
2752 return true;
2753 }
2754
2755 // Visit parameters and return type, if present.
2756 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2757 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2758 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2759 // Visit the whole type.
2760 if (Visit(TL))
2761 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002762 } else if (FunctionProtoTypeLoc Proto =
2763 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002764 if (E->hasExplicitParameters()) {
2765 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002766 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2767 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002768 return true;
2769 } else {
2770 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002771 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002772 return true;
2773 }
2774 }
2775 }
2776 break;
2777 }
2778
2779 case VisitorJob::PostChildrenVisitKind:
2780 if (PostChildrenVisitor(Parent, ClientData))
2781 return true;
2782 break;
2783 }
2784 }
2785 return false;
2786}
2787
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002788bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002789 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002790 if (!WorkListFreeList.empty()) {
2791 WL = WorkListFreeList.back();
2792 WL->clear();
2793 WorkListFreeList.pop_back();
2794 }
2795 else {
2796 WL = new VisitorWorkList();
2797 WorkListCache.push_back(WL);
2798 }
2799 EnqueueWorkList(*WL, S);
2800 bool result = RunVisitorWorkList(*WL);
2801 WorkListFreeList.push_back(WL);
2802 return result;
2803}
2804
2805namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002806typedef SmallVector<SourceRange, 4> RefNamePieces;
Craig Topper69186e72014-06-08 08:38:04 +00002807RefNamePieces
2808buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2809 const DeclarationNameInfo &NI, const SourceRange &QLoc,
2810 const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002811 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2812 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2813 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2814
2815 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2816
2817 RefNamePieces Pieces;
2818
2819 if (WantQualifier && QLoc.isValid())
2820 Pieces.push_back(QLoc);
2821
2822 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2823 Pieces.push_back(NI.getLoc());
2824
2825 if (WantTemplateArgs && TemplateArgs)
2826 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2827 TemplateArgs->RAngleLoc));
2828
2829 if (Kind == DeclarationName::CXXOperatorName) {
2830 Pieces.push_back(SourceLocation::getFromRawEncoding(
2831 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2832 Pieces.push_back(SourceLocation::getFromRawEncoding(
2833 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2834 }
2835
2836 if (WantSinglePiece) {
2837 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2838 Pieces.clear();
2839 Pieces.push_back(R);
2840 }
2841
2842 return Pieces;
2843}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002844}
Guy Benyei11169dd2012-12-18 14:30:41 +00002845
2846//===----------------------------------------------------------------------===//
2847// Misc. API hooks.
2848//===----------------------------------------------------------------------===//
2849
Chad Rosier05c71aa2013-03-27 18:28:23 +00002850static void fatal_error_handler(void *user_data, const std::string& reason,
2851 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002852 // Write the result out to stderr avoiding errs() because raw_ostreams can
2853 // call report_fatal_error.
2854 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2855 ::abort();
2856}
2857
Chandler Carruth66660742014-06-27 16:37:27 +00002858namespace {
2859struct RegisterFatalErrorHandler {
2860 RegisterFatalErrorHandler() {
2861 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2862 }
2863};
2864}
2865
2866static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
2867
Guy Benyei11169dd2012-12-18 14:30:41 +00002868extern "C" {
2869CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2870 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002871 // We use crash recovery to make some of our APIs more reliable, implicitly
2872 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002873 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2874 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002875
Chandler Carruth66660742014-06-27 16:37:27 +00002876 // Look through the managed static to trigger construction of the managed
2877 // static which registers our fatal error handler. This ensures it is only
2878 // registered once.
2879 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00002880
Adrian Prantlbc068582015-07-08 01:00:30 +00002881 // Initialize targets for clang module support.
2882 llvm::InitializeAllTargets();
2883 llvm::InitializeAllTargetMCs();
2884 llvm::InitializeAllAsmPrinters();
2885 llvm::InitializeAllAsmParsers();
2886
2887 CIndexer *CIdxr =
2888 new CIndexer(std::make_shared<ObjectFilePCHContainerOperations>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002889 if (excludeDeclarationsFromPCH)
2890 CIdxr->setOnlyLocalDecls();
2891 if (displayDiagnostics)
2892 CIdxr->setDisplayDiagnostics();
2893
2894 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2895 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2896 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2897 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2898 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2899 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2900
2901 return CIdxr;
2902}
2903
2904void clang_disposeIndex(CXIndex CIdx) {
2905 if (CIdx)
2906 delete static_cast<CIndexer *>(CIdx);
2907}
2908
2909void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2910 if (CIdx)
2911 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2912}
2913
2914unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2915 if (CIdx)
2916 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2917 return 0;
2918}
2919
2920void clang_toggleCrashRecovery(unsigned isEnabled) {
2921 if (isEnabled)
2922 llvm::CrashRecoveryContext::Enable();
2923 else
2924 llvm::CrashRecoveryContext::Disable();
2925}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002926
Guy Benyei11169dd2012-12-18 14:30:41 +00002927CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2928 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002929 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002930 enum CXErrorCode Result =
2931 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002932 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002933 assert((TU && Result == CXError_Success) ||
2934 (!TU && Result != CXError_Success));
2935 return TU;
2936}
2937
2938enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2939 const char *ast_filename,
2940 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002941 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002942 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002943
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002944 if (!CIdx || !ast_filename || !out_TU)
2945 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002946
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002947 LOG_FUNC_SECTION {
2948 *Log << ast_filename;
2949 }
2950
Guy Benyei11169dd2012-12-18 14:30:41 +00002951 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2952 FileSystemOptions FileSystemOpts;
2953
Justin Bognerd512c1e2014-10-15 00:33:06 +00002954 IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
2955 CompilerInstance::createDiagnostics(new DiagnosticOptions());
David Blaikie6f7382d2014-08-10 19:08:04 +00002956 std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
Adrian Prantlbb165fb2015-06-20 18:53:08 +00002957 ast_filename, CXXIdx->getPCHContainerOperations(), Diags, FileSystemOpts,
2958 CXXIdx->getOnlyLocalDecls(), None,
David Blaikie6f7382d2014-08-10 19:08:04 +00002959 /*CaptureDiagnostics=*/true,
2960 /*AllowPCHWithCompilerErrors=*/true,
2961 /*UserFilesAreVolatile=*/true);
2962 *out_TU = MakeCXTranslationUnit(CXXIdx, AU.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002963 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002964}
2965
2966unsigned clang_defaultEditingTranslationUnitOptions() {
2967 return CXTranslationUnit_PrecompiledPreamble |
2968 CXTranslationUnit_CacheCompletionResults;
2969}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002970
Guy Benyei11169dd2012-12-18 14:30:41 +00002971CXTranslationUnit
2972clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2973 const char *source_filename,
2974 int num_command_line_args,
2975 const char * const *command_line_args,
2976 unsigned num_unsaved_files,
2977 struct CXUnsavedFile *unsaved_files) {
2978 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2979 return clang_parseTranslationUnit(CIdx, source_filename,
2980 command_line_args, num_command_line_args,
2981 unsaved_files, num_unsaved_files,
2982 Options);
2983}
2984
2985struct ParseTranslationUnitInfo {
2986 CXIndex CIdx;
2987 const char *source_filename;
2988 const char *const *command_line_args;
2989 int num_command_line_args;
Alp Toker9d85b182014-07-07 01:23:14 +00002990 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00002991 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002992 CXTranslationUnit *out_TU;
Alp Toker5c532982014-07-07 22:42:03 +00002993 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002994};
2995static void clang_parseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00002996 const ParseTranslationUnitInfo *PTUI =
2997 static_cast<ParseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00002998 CXIndex CIdx = PTUI->CIdx;
2999 const char *source_filename = PTUI->source_filename;
3000 const char * const *command_line_args = PTUI->command_line_args;
3001 int num_command_line_args = PTUI->num_command_line_args;
Guy Benyei11169dd2012-12-18 14:30:41 +00003002 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003003 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00003004
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003005 // Set up the initial return values.
3006 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00003007 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003008
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003009 // Check arguments.
Alp Toker9d85b182014-07-07 01:23:14 +00003010 if (!CIdx || !out_TU) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003011 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00003012 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003013 }
3014
Guy Benyei11169dd2012-12-18 14:30:41 +00003015 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3016
3017 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3018 setThreadBackgroundPriority();
3019
3020 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
3021 // FIXME: Add a flag for modules.
3022 TranslationUnitKind TUKind
3023 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00003024 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00003025 = options & CXTranslationUnit_CacheCompletionResults;
3026 bool IncludeBriefCommentsInCodeCompletion
3027 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
3028 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
3029 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
3030
3031 // Configure the diagnostics.
3032 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00003033 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00003034
3035 // Recover resources if we crash before exiting this function.
3036 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
3037 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00003038 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00003039
Ahmed Charlesb8984322014-03-07 20:03:18 +00003040 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3041 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003042
3043 // Recover resources if we crash before exiting this function.
3044 llvm::CrashRecoveryContextCleanupRegistrar<
3045 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3046
Alp Toker9d85b182014-07-07 01:23:14 +00003047 for (auto &UF : PTUI->unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003048 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003049 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003050 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003051 }
3052
Ahmed Charlesb8984322014-03-07 20:03:18 +00003053 std::unique_ptr<std::vector<const char *>> Args(
3054 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003055
3056 // Recover resources if we crash before exiting this method.
3057 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
3058 ArgsCleanup(Args.get());
3059
3060 // Since the Clang C library is primarily used by batch tools dealing with
3061 // (often very broken) source code, where spell-checking can have a
3062 // significant negative impact on performance (particularly when
3063 // precompiled headers are involved), we disable it by default.
3064 // Only do this if we haven't found a spell-checking-related argument.
3065 bool FoundSpellCheckingArgument = false;
3066 for (int I = 0; I != num_command_line_args; ++I) {
3067 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
3068 strcmp(command_line_args[I], "-fspell-checking") == 0) {
3069 FoundSpellCheckingArgument = true;
3070 break;
3071 }
3072 }
3073 if (!FoundSpellCheckingArgument)
3074 Args->push_back("-fno-spell-checking");
3075
3076 Args->insert(Args->end(), command_line_args,
3077 command_line_args + num_command_line_args);
3078
3079 // The 'source_filename' argument is optional. If the caller does not
3080 // specify it then it is assumed that the source file is specified
3081 // in the actual argument list.
3082 // Put the source file after command_line_args otherwise if '-x' flag is
3083 // present it will be unused.
3084 if (source_filename)
3085 Args->push_back(source_filename);
3086
3087 // Do we need the detailed preprocessing record?
3088 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
3089 Args->push_back("-Xclang");
3090 Args->push_back("-detailed-preprocessing-record");
3091 }
3092
3093 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00003094 std::unique_ptr<ASTUnit> ErrUnit;
3095 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003096 Args->data(), Args->data() + Args->size(),
3097 CXXIdx->getPCHContainerOperations(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00003098 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
3099 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
3100 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
3101 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
3102 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
3103 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00003104
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003105 // Early failures in LoadFromCommandLine may return with ErrUnit unset.
3106 if (!Unit && !ErrUnit) {
3107 PTUI->result = CXError_ASTReadError;
3108 return;
3109 }
3110
Guy Benyei11169dd2012-12-18 14:30:41 +00003111 if (NumErrors != Diags->getClient()->getNumErrors()) {
3112 // Make sure to check that 'Unit' is non-NULL.
3113 if (CXXIdx->getDisplayDiagnostics())
3114 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
3115 }
3116
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003117 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
3118 PTUI->result = CXError_ASTReadError;
3119 } else {
Ahmed Charles9a16beb2014-03-07 19:33:25 +00003120 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003121 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
3122 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003123}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003124
3125CXTranslationUnit
3126clang_parseTranslationUnit(CXIndex CIdx,
3127 const char *source_filename,
3128 const char *const *command_line_args,
3129 int num_command_line_args,
3130 struct CXUnsavedFile *unsaved_files,
3131 unsigned num_unsaved_files,
3132 unsigned options) {
3133 CXTranslationUnit TU;
3134 enum CXErrorCode Result = clang_parseTranslationUnit2(
3135 CIdx, source_filename, command_line_args, num_command_line_args,
3136 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00003137 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003138 assert((TU && Result == CXError_Success) ||
3139 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003140 return TU;
3141}
3142
3143enum CXErrorCode clang_parseTranslationUnit2(
3144 CXIndex CIdx,
3145 const char *source_filename,
3146 const char *const *command_line_args,
3147 int num_command_line_args,
3148 struct CXUnsavedFile *unsaved_files,
3149 unsigned num_unsaved_files,
3150 unsigned options,
3151 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003152 LOG_FUNC_SECTION {
3153 *Log << source_filename << ": ";
3154 for (int i = 0; i != num_command_line_args; ++i)
3155 *Log << command_line_args[i] << " ";
3156 }
3157
Alp Toker9d85b182014-07-07 01:23:14 +00003158 if (num_unsaved_files && !unsaved_files)
3159 return CXError_InvalidArguments;
3160
Alp Toker5c532982014-07-07 22:42:03 +00003161 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00003162 ParseTranslationUnitInfo PTUI = {
3163 CIdx,
3164 source_filename,
3165 command_line_args,
3166 num_command_line_args,
3167 llvm::makeArrayRef(unsaved_files, num_unsaved_files),
3168 options,
3169 out_TU,
Alp Toker5c532982014-07-07 22:42:03 +00003170 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00003171 llvm::CrashRecoveryContext CRC;
3172
3173 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
3174 fprintf(stderr, "libclang: crash detected during parsing: {\n");
3175 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3176 fprintf(stderr, " 'command_line_args' : [");
3177 for (int i = 0; i != num_command_line_args; ++i) {
3178 if (i)
3179 fprintf(stderr, ", ");
3180 fprintf(stderr, "'%s'", command_line_args[i]);
3181 }
3182 fprintf(stderr, "],\n");
3183 fprintf(stderr, " 'unsaved_files' : [");
3184 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3185 if (i)
3186 fprintf(stderr, ", ");
3187 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3188 unsaved_files[i].Length);
3189 }
3190 fprintf(stderr, "],\n");
3191 fprintf(stderr, " 'options' : %d,\n", options);
3192 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003193
3194 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003195 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003196 if (CXTranslationUnit *TU = PTUI.out_TU)
3197 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003198 }
Alp Toker5c532982014-07-07 22:42:03 +00003199
3200 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003201}
3202
3203unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
3204 return CXSaveTranslationUnit_None;
3205}
3206
3207namespace {
3208
3209struct SaveTranslationUnitInfo {
3210 CXTranslationUnit TU;
3211 const char *FileName;
3212 unsigned options;
3213 CXSaveError result;
3214};
3215
3216}
3217
3218static void clang_saveTranslationUnit_Impl(void *UserData) {
3219 SaveTranslationUnitInfo *STUI =
3220 static_cast<SaveTranslationUnitInfo*>(UserData);
3221
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003222 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003223 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3224 setThreadBackgroundPriority();
3225
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003226 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00003227 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
3228}
3229
3230int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3231 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003232 LOG_FUNC_SECTION {
3233 *Log << TU << ' ' << FileName;
3234 }
3235
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003236 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003237 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003238 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003239 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003240
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003241 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003242 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3243 if (!CXXUnit->hasSema())
3244 return CXSaveError_InvalidTU;
3245
3246 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
3247
3248 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3249 getenv("LIBCLANG_NOTHREADS")) {
3250 clang_saveTranslationUnit_Impl(&STUI);
3251
3252 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3253 PrintLibclangResourceUsage(TU);
3254
3255 return STUI.result;
3256 }
3257
3258 // We have an AST that has invalid nodes due to compiler errors.
3259 // Use a crash recovery thread for protection.
3260
3261 llvm::CrashRecoveryContext CRC;
3262
3263 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
3264 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3265 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3266 fprintf(stderr, " 'options' : %d,\n", options);
3267 fprintf(stderr, "}\n");
3268
3269 return CXSaveError_Unknown;
3270
3271 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3272 PrintLibclangResourceUsage(TU);
3273 }
3274
3275 return STUI.result;
3276}
3277
3278void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3279 if (CTUnit) {
3280 // If the translation unit has been marked as unsafe to free, just discard
3281 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003282 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3283 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003284 return;
3285
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003286 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003287 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003288 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3289 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003290 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003291 delete CTUnit;
3292 }
3293}
3294
3295unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3296 return CXReparse_None;
3297}
3298
3299struct ReparseTranslationUnitInfo {
3300 CXTranslationUnit TU;
Alp Toker9d85b182014-07-07 01:23:14 +00003301 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00003302 unsigned options;
Alp Toker5c532982014-07-07 22:42:03 +00003303 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003304};
3305
3306static void clang_reparseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00003307 const ReparseTranslationUnitInfo *RTUI =
3308 static_cast<ReparseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00003309 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003310 unsigned options = RTUI->options;
3311 (void) options;
3312
3313 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003314 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003315 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003316 RTUI->result = CXError_InvalidArguments;
3317 return;
3318 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003319
3320 // Reset the associated diagnostics.
3321 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003322 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003323
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003324 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003325 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3326 setThreadBackgroundPriority();
3327
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003328 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003329 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003330
3331 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3332 new std::vector<ASTUnit::RemappedFile>());
3333
Guy Benyei11169dd2012-12-18 14:30:41 +00003334 // Recover resources if we crash before exiting this function.
3335 llvm::CrashRecoveryContextCleanupRegistrar<
3336 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003337
3338 for (auto &UF : RTUI->unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003339 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003340 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003341 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003342 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003343
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003344 if (!CXXUnit->Reparse(CXXIdx->getPCHContainerOperations(),
3345 *RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003346 RTUI->result = CXError_Success;
3347 else if (isASTReadError(CXXUnit))
3348 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003349}
3350
3351int clang_reparseTranslationUnit(CXTranslationUnit TU,
3352 unsigned num_unsaved_files,
3353 struct CXUnsavedFile *unsaved_files,
3354 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003355 LOG_FUNC_SECTION {
3356 *Log << TU;
3357 }
3358
Alp Toker9d85b182014-07-07 01:23:14 +00003359 if (num_unsaved_files && !unsaved_files)
3360 return CXError_InvalidArguments;
3361
Alp Toker5c532982014-07-07 22:42:03 +00003362 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00003363 ReparseTranslationUnitInfo RTUI = {
3364 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options,
Alp Toker5c532982014-07-07 22:42:03 +00003365 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00003366
3367 if (getenv("LIBCLANG_NOTHREADS")) {
3368 clang_reparseTranslationUnit_Impl(&RTUI);
Alp Toker5c532982014-07-07 22:42:03 +00003369 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003370 }
3371
3372 llvm::CrashRecoveryContext CRC;
3373
3374 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3375 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003376 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003377 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003378 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3379 PrintLibclangResourceUsage(TU);
3380
Alp Toker5c532982014-07-07 22:42:03 +00003381 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003382}
3383
3384
3385CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003386 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003387 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003388 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003389 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003390
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003391 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003392 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003393}
3394
3395CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003396 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003397 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003398 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003399 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003400
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003401 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003402 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3403}
3404
3405} // end: extern "C"
3406
3407//===----------------------------------------------------------------------===//
3408// CXFile Operations.
3409//===----------------------------------------------------------------------===//
3410
3411extern "C" {
3412CXString clang_getFileName(CXFile SFile) {
3413 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003414 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003415
3416 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003417 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003418}
3419
3420time_t clang_getFileTime(CXFile SFile) {
3421 if (!SFile)
3422 return 0;
3423
3424 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3425 return FEnt->getModificationTime();
3426}
3427
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003428CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003429 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003430 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003431 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003432 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003433
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003434 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003435
3436 FileManager &FMgr = CXXUnit->getFileManager();
3437 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3438}
3439
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003440unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3441 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003442 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003443 LOG_BAD_TU(TU);
3444 return 0;
3445 }
3446
3447 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003448 return 0;
3449
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003450 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003451 FileEntry *FEnt = static_cast<FileEntry *>(file);
3452 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3453 .isFileMultipleIncludeGuarded(FEnt);
3454}
3455
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003456int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3457 if (!file || !outID)
3458 return 1;
3459
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003460 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003461 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3462 outID->data[0] = ID.getDevice();
3463 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003464 outID->data[2] = FEnt->getModificationTime();
3465 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003466}
3467
Argyrios Kyrtzidisac3997e2014-08-16 00:26:19 +00003468int clang_File_isEqual(CXFile file1, CXFile file2) {
3469 if (file1 == file2)
3470 return true;
3471
3472 if (!file1 || !file2)
3473 return false;
3474
3475 FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
3476 FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
3477 return FEnt1->getUniqueID() == FEnt2->getUniqueID();
3478}
3479
Guy Benyei11169dd2012-12-18 14:30:41 +00003480} // end: extern "C"
3481
3482//===----------------------------------------------------------------------===//
3483// CXCursor Operations.
3484//===----------------------------------------------------------------------===//
3485
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003486static const Decl *getDeclFromExpr(const Stmt *E) {
3487 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003488 return getDeclFromExpr(CE->getSubExpr());
3489
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003490 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003491 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003492 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003493 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003494 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003495 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003496 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003497 if (PRE->isExplicitProperty())
3498 return PRE->getExplicitProperty();
3499 // It could be messaging both getter and setter as in:
3500 // ++myobj.myprop;
3501 // in which case prefer to associate the setter since it is less obvious
3502 // from inspecting the source that the setter is going to get called.
3503 if (PRE->isMessagingSetter())
3504 return PRE->getImplicitPropertySetter();
3505 return PRE->getImplicitPropertyGetter();
3506 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003507 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003508 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003509 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003510 if (Expr *Src = OVE->getSourceExpr())
3511 return getDeclFromExpr(Src);
3512
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003513 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003514 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003515 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003516 if (!CE->isElidable())
3517 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003518 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003519 return OME->getMethodDecl();
3520
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003521 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003522 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003523 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003524 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3525 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003526 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003527 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3528 isa<ParmVarDecl>(SizeOfPack->getPack()))
3529 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003530
3531 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003532}
3533
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003534static SourceLocation getLocationFromExpr(const Expr *E) {
3535 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003536 return getLocationFromExpr(CE->getSubExpr());
3537
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003538 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003539 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003540 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003541 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003542 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003543 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003544 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003545 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003546 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003547 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003548 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003549 return PropRef->getLocation();
3550
3551 return E->getLocStart();
3552}
3553
3554extern "C" {
3555
3556unsigned clang_visitChildren(CXCursor parent,
3557 CXCursorVisitor visitor,
3558 CXClientData client_data) {
3559 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3560 /*VisitPreprocessorLast=*/false);
3561 return CursorVis.VisitChildren(parent);
3562}
3563
3564#ifndef __has_feature
3565#define __has_feature(x) 0
3566#endif
3567#if __has_feature(blocks)
3568typedef enum CXChildVisitResult
3569 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3570
3571static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3572 CXClientData client_data) {
3573 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3574 return block(cursor, parent);
3575}
3576#else
3577// If we are compiled with a compiler that doesn't have native blocks support,
3578// define and call the block manually, so the
3579typedef struct _CXChildVisitResult
3580{
3581 void *isa;
3582 int flags;
3583 int reserved;
3584 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3585 CXCursor);
3586} *CXCursorVisitorBlock;
3587
3588static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3589 CXClientData client_data) {
3590 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3591 return block->invoke(block, cursor, parent);
3592}
3593#endif
3594
3595
3596unsigned clang_visitChildrenWithBlock(CXCursor parent,
3597 CXCursorVisitorBlock block) {
3598 return clang_visitChildren(parent, visitWithBlock, block);
3599}
3600
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003601static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003602 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003603 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003604
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003605 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003606 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003607 if (const ObjCPropertyImplDecl *PropImpl =
3608 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003609 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003610 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003611
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003612 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003613 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003614 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003615
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003616 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003617 }
3618
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003619 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003620 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003621
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003622 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003623 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3624 // and returns different names. NamedDecl returns the class name and
3625 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003626 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003627
3628 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003629 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003630
3631 SmallString<1024> S;
3632 llvm::raw_svector_ostream os(S);
3633 ND->printName(os);
3634
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003635 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003636}
3637
3638CXString clang_getCursorSpelling(CXCursor C) {
3639 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003640 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003641
3642 if (clang_isReference(C.kind)) {
3643 switch (C.kind) {
3644 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003645 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003646 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003647 }
3648 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003649 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003650 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003651 }
3652 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003653 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003654 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003655 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003656 }
3657 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003658 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003659 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003660 }
3661 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003662 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003663 assert(Type && "Missing type decl");
3664
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003665 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003666 getAsString());
3667 }
3668 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003669 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003670 assert(Template && "Missing template decl");
3671
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003672 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003673 }
3674
3675 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003676 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003677 assert(NS && "Missing namespace decl");
3678
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003679 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003680 }
3681
3682 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003683 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003684 assert(Field && "Missing member decl");
3685
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003686 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003687 }
3688
3689 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003690 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003691 assert(Label && "Missing label");
3692
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003693 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003694 }
3695
3696 case CXCursor_OverloadedDeclRef: {
3697 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003698 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3699 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003700 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003701 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003702 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003703 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003704 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003705 OverloadedTemplateStorage *Ovl
3706 = Storage.get<OverloadedTemplateStorage*>();
3707 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003708 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003709 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003710 }
3711
3712 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003713 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003714 assert(Var && "Missing variable decl");
3715
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003716 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003717 }
3718
3719 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003720 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003721 }
3722 }
3723
3724 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003725 const Expr *E = getCursorExpr(C);
3726
3727 if (C.kind == CXCursor_ObjCStringLiteral ||
3728 C.kind == CXCursor_StringLiteral) {
3729 const StringLiteral *SLit;
3730 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3731 SLit = OSL->getString();
3732 } else {
3733 SLit = cast<StringLiteral>(E);
3734 }
3735 SmallString<256> Buf;
3736 llvm::raw_svector_ostream OS(Buf);
3737 SLit->outputString(OS);
3738 return cxstring::createDup(OS.str());
3739 }
3740
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003741 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003742 if (D)
3743 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003744 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003745 }
3746
3747 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003748 const Stmt *S = getCursorStmt(C);
3749 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003750 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003751
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003752 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003753 }
3754
3755 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003756 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003757 ->getNameStart());
3758
3759 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003760 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003761 ->getNameStart());
3762
3763 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003764 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003765
3766 if (clang_isDeclaration(C.kind))
3767 return getDeclSpelling(getCursorDecl(C));
3768
3769 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003770 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003771 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003772 }
3773
3774 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003775 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003776 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003777 }
3778
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003779 if (C.kind == CXCursor_PackedAttr) {
3780 return cxstring::createRef("packed");
3781 }
3782
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003783 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003784}
3785
3786CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3787 unsigned pieceIndex,
3788 unsigned options) {
3789 if (clang_Cursor_isNull(C))
3790 return clang_getNullRange();
3791
3792 ASTContext &Ctx = getCursorContext(C);
3793
3794 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003795 const Stmt *S = getCursorStmt(C);
3796 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003797 if (pieceIndex > 0)
3798 return clang_getNullRange();
3799 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3800 }
3801
3802 return clang_getNullRange();
3803 }
3804
3805 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003806 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003807 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3808 if (pieceIndex >= ME->getNumSelectorLocs())
3809 return clang_getNullRange();
3810 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3811 }
3812 }
3813
3814 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3815 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003816 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003817 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3818 if (pieceIndex >= MD->getNumSelectorLocs())
3819 return clang_getNullRange();
3820 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3821 }
3822 }
3823
3824 if (C.kind == CXCursor_ObjCCategoryDecl ||
3825 C.kind == CXCursor_ObjCCategoryImplDecl) {
3826 if (pieceIndex > 0)
3827 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003828 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003829 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3830 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003831 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003832 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3833 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3834 }
3835
3836 if (C.kind == CXCursor_ModuleImportDecl) {
3837 if (pieceIndex > 0)
3838 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003839 if (const ImportDecl *ImportD =
3840 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003841 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3842 if (!Locs.empty())
3843 return cxloc::translateSourceRange(Ctx,
3844 SourceRange(Locs.front(), Locs.back()));
3845 }
3846 return clang_getNullRange();
3847 }
3848
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00003849 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
3850 C.kind == CXCursor_ConversionFunction) {
3851 if (pieceIndex > 0)
3852 return clang_getNullRange();
3853 if (const FunctionDecl *FD =
3854 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
3855 DeclarationNameInfo FunctionName = FD->getNameInfo();
3856 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
3857 }
3858 return clang_getNullRange();
3859 }
3860
Guy Benyei11169dd2012-12-18 14:30:41 +00003861 // FIXME: A CXCursor_InclusionDirective should give the location of the
3862 // filename, but we don't keep track of this.
3863
3864 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3865 // but we don't keep track of this.
3866
3867 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3868 // but we don't keep track of this.
3869
3870 // Default handling, give the location of the cursor.
3871
3872 if (pieceIndex > 0)
3873 return clang_getNullRange();
3874
3875 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3876 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3877 return cxloc::translateSourceRange(Ctx, Loc);
3878}
3879
Eli Bendersky44a206f2014-07-31 18:04:56 +00003880CXString clang_Cursor_getMangling(CXCursor C) {
3881 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
3882 return cxstring::createEmpty();
3883
Eli Bendersky44a206f2014-07-31 18:04:56 +00003884 // Mangling only works for functions and variables.
Eli Bendersky79759592014-08-01 15:01:10 +00003885 const Decl *D = getCursorDecl(C);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003886 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
3887 return cxstring::createEmpty();
3888
Eli Bendersky79759592014-08-01 15:01:10 +00003889 // First apply frontend mangling.
Eli Bendersky44a206f2014-07-31 18:04:56 +00003890 const NamedDecl *ND = cast<NamedDecl>(D);
Eli Bendersky79759592014-08-01 15:01:10 +00003891 ASTContext &Ctx = ND->getASTContext();
3892 std::unique_ptr<MangleContext> MC(Ctx.createMangleContext());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003893
Eli Bendersky79759592014-08-01 15:01:10 +00003894 std::string FrontendBuf;
3895 llvm::raw_string_ostream FrontendBufOS(FrontendBuf);
3896 MC->mangleName(ND, FrontendBufOS);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003897
Eli Bendersky79759592014-08-01 15:01:10 +00003898 // Now apply backend mangling.
3899 std::unique_ptr<llvm::DataLayout> DL(
3900 new llvm::DataLayout(Ctx.getTargetInfo().getTargetDescription()));
Eli Bendersky79759592014-08-01 15:01:10 +00003901
3902 std::string FinalBuf;
3903 llvm::raw_string_ostream FinalBufOS(FinalBuf);
Rafael Espindolab633d202015-06-23 13:59:36 +00003904 llvm::Mangler::getNameWithPrefix(FinalBufOS, llvm::Twine(FrontendBufOS.str()),
3905 *DL);
Eli Bendersky79759592014-08-01 15:01:10 +00003906
3907 return cxstring::createDup(FinalBufOS.str());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003908}
3909
Guy Benyei11169dd2012-12-18 14:30:41 +00003910CXString clang_getCursorDisplayName(CXCursor C) {
3911 if (!clang_isDeclaration(C.kind))
3912 return clang_getCursorSpelling(C);
3913
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003914 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003915 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003916 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003917
3918 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003919 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003920 D = FunTmpl->getTemplatedDecl();
3921
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003922 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003923 SmallString<64> Str;
3924 llvm::raw_svector_ostream OS(Str);
3925 OS << *Function;
3926 if (Function->getPrimaryTemplate())
3927 OS << "<>";
3928 OS << "(";
3929 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3930 if (I)
3931 OS << ", ";
3932 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3933 }
3934
3935 if (Function->isVariadic()) {
3936 if (Function->getNumParams())
3937 OS << ", ";
3938 OS << "...";
3939 }
3940 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003941 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003942 }
3943
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003944 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003945 SmallString<64> Str;
3946 llvm::raw_svector_ostream OS(Str);
3947 OS << *ClassTemplate;
3948 OS << "<";
3949 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3950 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3951 if (I)
3952 OS << ", ";
3953
3954 NamedDecl *Param = Params->getParam(I);
3955 if (Param->getIdentifier()) {
3956 OS << Param->getIdentifier()->getName();
3957 continue;
3958 }
3959
3960 // There is no parameter name, which makes this tricky. Try to come up
3961 // with something useful that isn't too long.
3962 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3963 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3964 else if (NonTypeTemplateParmDecl *NTTP
3965 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3966 OS << NTTP->getType().getAsString(Policy);
3967 else
3968 OS << "template<...> class";
3969 }
3970
3971 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003972 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003973 }
3974
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003975 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003976 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3977 // If the type was explicitly written, use that.
3978 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003979 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003980
Benjamin Kramer9170e912013-02-22 15:46:01 +00003981 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003982 llvm::raw_svector_ostream OS(Str);
3983 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003984 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003985 ClassSpec->getTemplateArgs().data(),
3986 ClassSpec->getTemplateArgs().size(),
3987 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003988 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003989 }
3990
3991 return clang_getCursorSpelling(C);
3992}
3993
3994CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3995 switch (Kind) {
3996 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003997 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003998 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003999 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004000 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004001 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004002 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004003 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004004 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004005 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004006 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004007 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004008 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004009 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004010 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004011 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004012 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004013 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004014 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004015 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004016 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004017 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004018 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004019 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004020 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004021 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004022 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004023 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004024 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004025 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004026 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004027 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004028 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004029 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004030 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004031 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004032 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004033 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004034 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004035 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00004036 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004037 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004038 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004039 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004040 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004041 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004042 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004043 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004044 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004045 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004046 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004047 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004048 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004049 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004050 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004051 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004052 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004053 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004054 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004055 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004056 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004057 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004058 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004059 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004060 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004061 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004062 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004063 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004064 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004065 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004066 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004067 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004068 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004069 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004070 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004071 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004072 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004073 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004074 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004075 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004076 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004077 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004078 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004079 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004080 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004081 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004082 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004083 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004084 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004085 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004086 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004087 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004088 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004089 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004090 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004091 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004092 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004093 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004094 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004095 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004096 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004097 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004098 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004099 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004100 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004101 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004102 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004103 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004104 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004105 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004106 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004107 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004108 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004109 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004110 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004111 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004112 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004113 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004114 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004115 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004116 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004117 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004118 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004119 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004120 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004121 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004122 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004123 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00004124 case CXCursor_ObjCSelfExpr:
4125 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004126 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004127 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004128 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004129 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004130 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004131 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004132 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004133 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004134 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004135 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004136 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004137 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004138 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004139 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004140 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004141 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004142 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004143 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004144 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004145 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004146 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004147 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004148 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004149 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004150 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004151 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004152 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004153 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004154 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004155 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004156 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004157 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004158 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004159 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004160 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004161 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004162 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004163 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004164 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004165 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004166 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004167 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004168 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004169 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004170 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004171 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004172 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004173 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004174 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004175 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004176 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004177 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004178 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004179 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004180 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004181 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004182 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004183 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004184 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004185 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004186 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004187 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004188 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004189 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004190 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004191 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004192 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004193 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004194 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004195 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004196 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004197 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004198 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004199 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004200 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004201 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004202 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004203 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004204 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004205 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004206 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004207 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004208 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004209 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004210 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004211 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004212 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004213 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00004214 case CXCursor_SEHLeaveStmt:
4215 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004216 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004217 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004218 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004219 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00004220 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004221 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00004222 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004223 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00004224 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004225 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00004226 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004227 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00004228 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004229 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004230 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004231 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004232 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004233 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004234 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004235 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004236 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004237 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004238 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004239 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004240 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004241 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004242 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004243 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004244 case CXCursor_PackedAttr:
4245 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00004246 case CXCursor_PureAttr:
4247 return cxstring::createRef("attribute(pure)");
4248 case CXCursor_ConstAttr:
4249 return cxstring::createRef("attribute(const)");
4250 case CXCursor_NoDuplicateAttr:
4251 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00004252 case CXCursor_CUDAConstantAttr:
4253 return cxstring::createRef("attribute(constant)");
4254 case CXCursor_CUDADeviceAttr:
4255 return cxstring::createRef("attribute(device)");
4256 case CXCursor_CUDAGlobalAttr:
4257 return cxstring::createRef("attribute(global)");
4258 case CXCursor_CUDAHostAttr:
4259 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00004260 case CXCursor_CUDASharedAttr:
4261 return cxstring::createRef("attribute(shared)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004262 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004263 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004264 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004265 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00004266 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004267 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004268 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004269 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004270 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004271 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00004272 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004273 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00004274 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004275 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004276 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004277 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004278 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004279 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004280 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004281 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004282 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004283 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004284 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004285 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004286 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004287 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004288 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004289 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004290 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004291 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004292 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004293 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004294 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004295 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004296 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004297 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004298 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004299 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004300 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004301 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004302 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004303 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004304 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004305 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004306 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004307 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004308 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004309 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004310 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004311 return cxstring::createRef("OMPParallelDirective");
4312 case CXCursor_OMPSimdDirective:
4313 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004314 case CXCursor_OMPForDirective:
4315 return cxstring::createRef("OMPForDirective");
Alexander Musmanf82886e2014-09-18 05:12:34 +00004316 case CXCursor_OMPForSimdDirective:
4317 return cxstring::createRef("OMPForSimdDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004318 case CXCursor_OMPSectionsDirective:
4319 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004320 case CXCursor_OMPSectionDirective:
4321 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004322 case CXCursor_OMPSingleDirective:
4323 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004324 case CXCursor_OMPMasterDirective:
4325 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004326 case CXCursor_OMPCriticalDirective:
4327 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004328 case CXCursor_OMPParallelForDirective:
4329 return cxstring::createRef("OMPParallelForDirective");
Alexander Musmane4e893b2014-09-23 09:33:00 +00004330 case CXCursor_OMPParallelForSimdDirective:
4331 return cxstring::createRef("OMPParallelForSimdDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004332 case CXCursor_OMPParallelSectionsDirective:
4333 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004334 case CXCursor_OMPTaskDirective:
4335 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004336 case CXCursor_OMPTaskyieldDirective:
4337 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004338 case CXCursor_OMPBarrierDirective:
4339 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004340 case CXCursor_OMPTaskwaitDirective:
4341 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00004342 case CXCursor_OMPTaskgroupDirective:
4343 return cxstring::createRef("OMPTaskgroupDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00004344 case CXCursor_OMPFlushDirective:
4345 return cxstring::createRef("OMPFlushDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004346 case CXCursor_OMPOrderedDirective:
4347 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00004348 case CXCursor_OMPAtomicDirective:
4349 return cxstring::createRef("OMPAtomicDirective");
Alexey Bataev0bd520b2014-09-19 08:19:49 +00004350 case CXCursor_OMPTargetDirective:
4351 return cxstring::createRef("OMPTargetDirective");
Alexey Bataev13314bf2014-10-09 04:18:56 +00004352 case CXCursor_OMPTeamsDirective:
4353 return cxstring::createRef("OMPTeamsDirective");
Alexey Bataev6d4ed052015-07-01 06:57:41 +00004354 case CXCursor_OMPCancellationPointDirective:
4355 return cxstring::createRef("OMPCancellationPointDirective");
Alexey Bataev80909872015-07-02 11:25:17 +00004356 case CXCursor_OMPCancelDirective:
4357 return cxstring::createRef("OMPCancelDirective");
Francisco Lopes da Silva975a9f62015-01-21 16:24:11 +00004358 case CXCursor_OverloadCandidate:
4359 return cxstring::createRef("OverloadCandidate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004360 }
4361
4362 llvm_unreachable("Unhandled CXCursorKind");
4363}
4364
4365struct GetCursorData {
4366 SourceLocation TokenBeginLoc;
4367 bool PointsAtMacroArgExpansion;
4368 bool VisitedObjCPropertyImplDecl;
4369 SourceLocation VisitedDeclaratorDeclStartLoc;
4370 CXCursor &BestCursor;
4371
4372 GetCursorData(SourceManager &SM,
4373 SourceLocation tokenBegin, CXCursor &outputCursor)
4374 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4375 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4376 VisitedObjCPropertyImplDecl = false;
4377 }
4378};
4379
4380static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4381 CXCursor parent,
4382 CXClientData client_data) {
4383 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4384 CXCursor *BestCursor = &Data->BestCursor;
4385
4386 // If we point inside a macro argument we should provide info of what the
4387 // token is so use the actual cursor, don't replace it with a macro expansion
4388 // cursor.
4389 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4390 return CXChildVisit_Recurse;
4391
4392 if (clang_isDeclaration(cursor.kind)) {
4393 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004394 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004395 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4396 if (MD->isImplicit())
4397 return CXChildVisit_Break;
4398
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004399 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004400 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4401 // Check that when we have multiple @class references in the same line,
4402 // that later ones do not override the previous ones.
4403 // If we have:
4404 // @class Foo, Bar;
4405 // source ranges for both start at '@', so 'Bar' will end up overriding
4406 // 'Foo' even though the cursor location was at 'Foo'.
4407 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4408 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004409 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004410 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4411 if (PrevID != ID &&
4412 !PrevID->isThisDeclarationADefinition() &&
4413 !ID->isThisDeclarationADefinition())
4414 return CXChildVisit_Break;
4415 }
4416
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004417 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004418 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4419 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4420 // Check that when we have multiple declarators in the same line,
4421 // that later ones do not override the previous ones.
4422 // If we have:
4423 // int Foo, Bar;
4424 // source ranges for both start at 'int', so 'Bar' will end up overriding
4425 // 'Foo' even though the cursor location was at 'Foo'.
4426 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4427 return CXChildVisit_Break;
4428 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4429
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004430 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004431 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4432 (void)PropImp;
4433 // Check that when we have multiple @synthesize in the same line,
4434 // that later ones do not override the previous ones.
4435 // If we have:
4436 // @synthesize Foo, Bar;
4437 // source ranges for both start at '@', so 'Bar' will end up overriding
4438 // 'Foo' even though the cursor location was at 'Foo'.
4439 if (Data->VisitedObjCPropertyImplDecl)
4440 return CXChildVisit_Break;
4441 Data->VisitedObjCPropertyImplDecl = true;
4442 }
4443 }
4444
4445 if (clang_isExpression(cursor.kind) &&
4446 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004447 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004448 // Avoid having the cursor of an expression replace the declaration cursor
4449 // when the expression source range overlaps the declaration range.
4450 // This can happen for C++ constructor expressions whose range generally
4451 // include the variable declaration, e.g.:
4452 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4453 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4454 D->getLocation() == Data->TokenBeginLoc)
4455 return CXChildVisit_Break;
4456 }
4457 }
4458
4459 // If our current best cursor is the construction of a temporary object,
4460 // don't replace that cursor with a type reference, because we want
4461 // clang_getCursor() to point at the constructor.
4462 if (clang_isExpression(BestCursor->kind) &&
4463 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4464 cursor.kind == CXCursor_TypeRef) {
4465 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4466 // as having the actual point on the type reference.
4467 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4468 return CXChildVisit_Recurse;
4469 }
Douglas Gregore9d95f12015-07-07 03:57:35 +00004470
4471 // If we already have an Objective-C superclass reference, don't
4472 // update it further.
4473 if (BestCursor->kind == CXCursor_ObjCSuperClassRef)
4474 return CXChildVisit_Break;
4475
Guy Benyei11169dd2012-12-18 14:30:41 +00004476 *BestCursor = cursor;
4477 return CXChildVisit_Recurse;
4478}
4479
4480CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004481 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004482 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004483 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004484 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004485
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004486 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004487 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4488
4489 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4490 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4491
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004492 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004493 CXFile SearchFile;
4494 unsigned SearchLine, SearchColumn;
4495 CXFile ResultFile;
4496 unsigned ResultLine, ResultColumn;
4497 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4498 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4499 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004500
4501 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4502 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004503 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004504 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004505 SearchFileName = clang_getFileName(SearchFile);
4506 ResultFileName = clang_getFileName(ResultFile);
4507 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4508 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004509 *Log << llvm::format("(%s:%d:%d) = %s",
4510 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4511 clang_getCString(KindSpelling))
4512 << llvm::format("(%s:%d:%d):%s%s",
4513 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4514 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004515 clang_disposeString(SearchFileName);
4516 clang_disposeString(ResultFileName);
4517 clang_disposeString(KindSpelling);
4518 clang_disposeString(USR);
4519
4520 CXCursor Definition = clang_getCursorDefinition(Result);
4521 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4522 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4523 CXString DefinitionKindSpelling
4524 = clang_getCursorKindSpelling(Definition.kind);
4525 CXFile DefinitionFile;
4526 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004527 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004528 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004529 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004530 *Log << llvm::format(" -> %s(%s:%d:%d)",
4531 clang_getCString(DefinitionKindSpelling),
4532 clang_getCString(DefinitionFileName),
4533 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004534 clang_disposeString(DefinitionFileName);
4535 clang_disposeString(DefinitionKindSpelling);
4536 }
4537 }
4538
4539 return Result;
4540}
4541
4542CXCursor clang_getNullCursor(void) {
4543 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4544}
4545
4546unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004547 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4548 // can't set consistently. For example, when visiting a DeclStmt we will set
4549 // it but we don't set it on the result of clang_getCursorDefinition for
4550 // a reference of the same declaration.
4551 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4552 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4553 // to provide that kind of info.
4554 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004555 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004556 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004557 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004558
Guy Benyei11169dd2012-12-18 14:30:41 +00004559 return X == Y;
4560}
4561
4562unsigned clang_hashCursor(CXCursor C) {
4563 unsigned Index = 0;
4564 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4565 Index = 1;
4566
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004567 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004568 std::make_pair(C.kind, C.data[Index]));
4569}
4570
4571unsigned clang_isInvalid(enum CXCursorKind K) {
4572 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4573}
4574
4575unsigned clang_isDeclaration(enum CXCursorKind K) {
4576 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4577 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4578}
4579
4580unsigned clang_isReference(enum CXCursorKind K) {
4581 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4582}
4583
4584unsigned clang_isExpression(enum CXCursorKind K) {
4585 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4586}
4587
4588unsigned clang_isStatement(enum CXCursorKind K) {
4589 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4590}
4591
4592unsigned clang_isAttribute(enum CXCursorKind K) {
4593 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4594}
4595
4596unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4597 return K == CXCursor_TranslationUnit;
4598}
4599
4600unsigned clang_isPreprocessing(enum CXCursorKind K) {
4601 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4602}
4603
4604unsigned clang_isUnexposed(enum CXCursorKind K) {
4605 switch (K) {
4606 case CXCursor_UnexposedDecl:
4607 case CXCursor_UnexposedExpr:
4608 case CXCursor_UnexposedStmt:
4609 case CXCursor_UnexposedAttr:
4610 return true;
4611 default:
4612 return false;
4613 }
4614}
4615
4616CXCursorKind clang_getCursorKind(CXCursor C) {
4617 return C.kind;
4618}
4619
4620CXSourceLocation clang_getCursorLocation(CXCursor C) {
4621 if (clang_isReference(C.kind)) {
4622 switch (C.kind) {
4623 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004624 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004625 = getCursorObjCSuperClassRef(C);
4626 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4627 }
4628
4629 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004630 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004631 = getCursorObjCProtocolRef(C);
4632 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4633 }
4634
4635 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004636 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004637 = getCursorObjCClassRef(C);
4638 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4639 }
4640
4641 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004642 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004643 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4644 }
4645
4646 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004647 std::pair<const TemplateDecl *, SourceLocation> P =
4648 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004649 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4650 }
4651
4652 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004653 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004654 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4655 }
4656
4657 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004658 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004659 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4660 }
4661
4662 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004663 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004664 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4665 }
4666
4667 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004668 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004669 if (!BaseSpec)
4670 return clang_getNullLocation();
4671
4672 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4673 return cxloc::translateSourceLocation(getCursorContext(C),
4674 TSInfo->getTypeLoc().getBeginLoc());
4675
4676 return cxloc::translateSourceLocation(getCursorContext(C),
4677 BaseSpec->getLocStart());
4678 }
4679
4680 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004681 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004682 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4683 }
4684
4685 case CXCursor_OverloadedDeclRef:
4686 return cxloc::translateSourceLocation(getCursorContext(C),
4687 getCursorOverloadedDeclRef(C).second);
4688
4689 default:
4690 // FIXME: Need a way to enumerate all non-reference cases.
4691 llvm_unreachable("Missed a reference kind");
4692 }
4693 }
4694
4695 if (clang_isExpression(C.kind))
4696 return cxloc::translateSourceLocation(getCursorContext(C),
4697 getLocationFromExpr(getCursorExpr(C)));
4698
4699 if (clang_isStatement(C.kind))
4700 return cxloc::translateSourceLocation(getCursorContext(C),
4701 getCursorStmt(C)->getLocStart());
4702
4703 if (C.kind == CXCursor_PreprocessingDirective) {
4704 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4705 return cxloc::translateSourceLocation(getCursorContext(C), L);
4706 }
4707
4708 if (C.kind == CXCursor_MacroExpansion) {
4709 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004710 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004711 return cxloc::translateSourceLocation(getCursorContext(C), L);
4712 }
4713
4714 if (C.kind == CXCursor_MacroDefinition) {
4715 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4716 return cxloc::translateSourceLocation(getCursorContext(C), L);
4717 }
4718
4719 if (C.kind == CXCursor_InclusionDirective) {
4720 SourceLocation L
4721 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4722 return cxloc::translateSourceLocation(getCursorContext(C), L);
4723 }
4724
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004725 if (clang_isAttribute(C.kind)) {
4726 SourceLocation L
4727 = cxcursor::getCursorAttr(C)->getLocation();
4728 return cxloc::translateSourceLocation(getCursorContext(C), L);
4729 }
4730
Guy Benyei11169dd2012-12-18 14:30:41 +00004731 if (!clang_isDeclaration(C.kind))
4732 return clang_getNullLocation();
4733
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004734 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004735 if (!D)
4736 return clang_getNullLocation();
4737
4738 SourceLocation Loc = D->getLocation();
4739 // FIXME: Multiple variables declared in a single declaration
4740 // currently lack the information needed to correctly determine their
4741 // ranges when accounting for the type-specifier. We use context
4742 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4743 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004744 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004745 if (!cxcursor::isFirstInDeclGroup(C))
4746 Loc = VD->getLocation();
4747 }
4748
4749 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004750 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004751 Loc = MD->getSelectorStartLoc();
4752
4753 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4754}
4755
4756} // end extern "C"
4757
4758CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4759 assert(TU);
4760
4761 // Guard against an invalid SourceLocation, or we may assert in one
4762 // of the following calls.
4763 if (SLoc.isInvalid())
4764 return clang_getNullCursor();
4765
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004766 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004767
4768 // Translate the given source location to make it point at the beginning of
4769 // the token under the cursor.
4770 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4771 CXXUnit->getASTContext().getLangOpts());
4772
4773 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4774 if (SLoc.isValid()) {
4775 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4776 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4777 /*VisitPreprocessorLast=*/true,
4778 /*VisitIncludedEntities=*/false,
4779 SourceLocation(SLoc));
4780 CursorVis.visitFileRegion();
4781 }
4782
4783 return Result;
4784}
4785
4786static SourceRange getRawCursorExtent(CXCursor C) {
4787 if (clang_isReference(C.kind)) {
4788 switch (C.kind) {
4789 case CXCursor_ObjCSuperClassRef:
4790 return getCursorObjCSuperClassRef(C).second;
4791
4792 case CXCursor_ObjCProtocolRef:
4793 return getCursorObjCProtocolRef(C).second;
4794
4795 case CXCursor_ObjCClassRef:
4796 return getCursorObjCClassRef(C).second;
4797
4798 case CXCursor_TypeRef:
4799 return getCursorTypeRef(C).second;
4800
4801 case CXCursor_TemplateRef:
4802 return getCursorTemplateRef(C).second;
4803
4804 case CXCursor_NamespaceRef:
4805 return getCursorNamespaceRef(C).second;
4806
4807 case CXCursor_MemberRef:
4808 return getCursorMemberRef(C).second;
4809
4810 case CXCursor_CXXBaseSpecifier:
4811 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4812
4813 case CXCursor_LabelRef:
4814 return getCursorLabelRef(C).second;
4815
4816 case CXCursor_OverloadedDeclRef:
4817 return getCursorOverloadedDeclRef(C).second;
4818
4819 case CXCursor_VariableRef:
4820 return getCursorVariableRef(C).second;
4821
4822 default:
4823 // FIXME: Need a way to enumerate all non-reference cases.
4824 llvm_unreachable("Missed a reference kind");
4825 }
4826 }
4827
4828 if (clang_isExpression(C.kind))
4829 return getCursorExpr(C)->getSourceRange();
4830
4831 if (clang_isStatement(C.kind))
4832 return getCursorStmt(C)->getSourceRange();
4833
4834 if (clang_isAttribute(C.kind))
4835 return getCursorAttr(C)->getRange();
4836
4837 if (C.kind == CXCursor_PreprocessingDirective)
4838 return cxcursor::getCursorPreprocessingDirective(C);
4839
4840 if (C.kind == CXCursor_MacroExpansion) {
4841 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004842 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004843 return TU->mapRangeFromPreamble(Range);
4844 }
4845
4846 if (C.kind == CXCursor_MacroDefinition) {
4847 ASTUnit *TU = getCursorASTUnit(C);
4848 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4849 return TU->mapRangeFromPreamble(Range);
4850 }
4851
4852 if (C.kind == CXCursor_InclusionDirective) {
4853 ASTUnit *TU = getCursorASTUnit(C);
4854 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4855 return TU->mapRangeFromPreamble(Range);
4856 }
4857
4858 if (C.kind == CXCursor_TranslationUnit) {
4859 ASTUnit *TU = getCursorASTUnit(C);
4860 FileID MainID = TU->getSourceManager().getMainFileID();
4861 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4862 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4863 return SourceRange(Start, End);
4864 }
4865
4866 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004867 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004868 if (!D)
4869 return SourceRange();
4870
4871 SourceRange R = D->getSourceRange();
4872 // FIXME: Multiple variables declared in a single declaration
4873 // currently lack the information needed to correctly determine their
4874 // ranges when accounting for the type-specifier. We use context
4875 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4876 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004877 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004878 if (!cxcursor::isFirstInDeclGroup(C))
4879 R.setBegin(VD->getLocation());
4880 }
4881 return R;
4882 }
4883 return SourceRange();
4884}
4885
4886/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4887/// the decl-specifier-seq for declarations.
4888static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4889 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004890 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004891 if (!D)
4892 return SourceRange();
4893
4894 SourceRange R = D->getSourceRange();
4895
4896 // Adjust the start of the location for declarations preceded by
4897 // declaration specifiers.
4898 SourceLocation StartLoc;
4899 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4900 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4901 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004902 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004903 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4904 StartLoc = TI->getTypeLoc().getLocStart();
4905 }
4906
4907 if (StartLoc.isValid() && R.getBegin().isValid() &&
4908 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4909 R.setBegin(StartLoc);
4910
4911 // FIXME: Multiple variables declared in a single declaration
4912 // currently lack the information needed to correctly determine their
4913 // ranges when accounting for the type-specifier. We use context
4914 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4915 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004916 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004917 if (!cxcursor::isFirstInDeclGroup(C))
4918 R.setBegin(VD->getLocation());
4919 }
4920
4921 return R;
4922 }
4923
4924 return getRawCursorExtent(C);
4925}
4926
4927extern "C" {
4928
4929CXSourceRange clang_getCursorExtent(CXCursor C) {
4930 SourceRange R = getRawCursorExtent(C);
4931 if (R.isInvalid())
4932 return clang_getNullRange();
4933
4934 return cxloc::translateSourceRange(getCursorContext(C), R);
4935}
4936
4937CXCursor clang_getCursorReferenced(CXCursor C) {
4938 if (clang_isInvalid(C.kind))
4939 return clang_getNullCursor();
4940
4941 CXTranslationUnit tu = getCursorTU(C);
4942 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004943 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004944 if (!D)
4945 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004946 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004947 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004948 if (const ObjCPropertyImplDecl *PropImpl =
4949 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004950 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4951 return MakeCXCursor(Property, tu);
4952
4953 return C;
4954 }
4955
4956 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004957 const Expr *E = getCursorExpr(C);
4958 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004959 if (D) {
4960 CXCursor declCursor = MakeCXCursor(D, tu);
4961 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4962 declCursor);
4963 return declCursor;
4964 }
4965
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004966 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004967 return MakeCursorOverloadedDeclRef(Ovl, tu);
4968
4969 return clang_getNullCursor();
4970 }
4971
4972 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004973 const Stmt *S = getCursorStmt(C);
4974 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004975 if (LabelDecl *label = Goto->getLabel())
4976 if (LabelStmt *labelS = label->getStmt())
4977 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4978
4979 return clang_getNullCursor();
4980 }
Richard Smith66a81862015-05-04 02:25:31 +00004981
Guy Benyei11169dd2012-12-18 14:30:41 +00004982 if (C.kind == CXCursor_MacroExpansion) {
Richard Smith66a81862015-05-04 02:25:31 +00004983 if (const MacroDefinitionRecord *Def =
4984 getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004985 return MakeMacroDefinitionCursor(Def, tu);
4986 }
4987
4988 if (!clang_isReference(C.kind))
4989 return clang_getNullCursor();
4990
4991 switch (C.kind) {
4992 case CXCursor_ObjCSuperClassRef:
4993 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4994
4995 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004996 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4997 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004998 return MakeCXCursor(Def, tu);
4999
5000 return MakeCXCursor(Prot, tu);
5001 }
5002
5003 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005004 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
5005 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005006 return MakeCXCursor(Def, tu);
5007
5008 return MakeCXCursor(Class, tu);
5009 }
5010
5011 case CXCursor_TypeRef:
5012 return MakeCXCursor(getCursorTypeRef(C).first, tu );
5013
5014 case CXCursor_TemplateRef:
5015 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
5016
5017 case CXCursor_NamespaceRef:
5018 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
5019
5020 case CXCursor_MemberRef:
5021 return MakeCXCursor(getCursorMemberRef(C).first, tu );
5022
5023 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005024 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005025 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
5026 tu ));
5027 }
5028
5029 case CXCursor_LabelRef:
5030 // FIXME: We end up faking the "parent" declaration here because we
5031 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005032 return MakeCXCursor(getCursorLabelRef(C).first,
5033 cxtu::getASTUnit(tu)->getASTContext()
5034 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00005035 tu);
5036
5037 case CXCursor_OverloadedDeclRef:
5038 return C;
5039
5040 case CXCursor_VariableRef:
5041 return MakeCXCursor(getCursorVariableRef(C).first, tu);
5042
5043 default:
5044 // We would prefer to enumerate all non-reference cursor kinds here.
5045 llvm_unreachable("Unhandled reference cursor kind");
5046 }
5047}
5048
5049CXCursor clang_getCursorDefinition(CXCursor C) {
5050 if (clang_isInvalid(C.kind))
5051 return clang_getNullCursor();
5052
5053 CXTranslationUnit TU = getCursorTU(C);
5054
5055 bool WasReference = false;
5056 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
5057 C = clang_getCursorReferenced(C);
5058 WasReference = true;
5059 }
5060
5061 if (C.kind == CXCursor_MacroExpansion)
5062 return clang_getCursorReferenced(C);
5063
5064 if (!clang_isDeclaration(C.kind))
5065 return clang_getNullCursor();
5066
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005067 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005068 if (!D)
5069 return clang_getNullCursor();
5070
5071 switch (D->getKind()) {
5072 // Declaration kinds that don't really separate the notions of
5073 // declaration and definition.
5074 case Decl::Namespace:
5075 case Decl::Typedef:
5076 case Decl::TypeAlias:
5077 case Decl::TypeAliasTemplate:
5078 case Decl::TemplateTypeParm:
5079 case Decl::EnumConstant:
5080 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00005081 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005082 case Decl::IndirectField:
5083 case Decl::ObjCIvar:
5084 case Decl::ObjCAtDefsField:
5085 case Decl::ImplicitParam:
5086 case Decl::ParmVar:
5087 case Decl::NonTypeTemplateParm:
5088 case Decl::TemplateTemplateParm:
5089 case Decl::ObjCCategoryImpl:
5090 case Decl::ObjCImplementation:
5091 case Decl::AccessSpec:
5092 case Decl::LinkageSpec:
5093 case Decl::ObjCPropertyImpl:
5094 case Decl::FileScopeAsm:
5095 case Decl::StaticAssert:
5096 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00005097 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00005098 case Decl::Label: // FIXME: Is this right??
5099 case Decl::ClassScopeFunctionSpecialization:
5100 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00005101 case Decl::OMPThreadPrivate:
Douglas Gregor85f3f952015-07-07 03:57:15 +00005102 case Decl::ObjCTypeParam:
Guy Benyei11169dd2012-12-18 14:30:41 +00005103 return C;
5104
5105 // Declaration kinds that don't make any sense here, but are
5106 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00005107 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005108 case Decl::TranslationUnit:
Richard Smithf19e1272015-03-07 00:04:49 +00005109 case Decl::ExternCContext:
Guy Benyei11169dd2012-12-18 14:30:41 +00005110 break;
5111
5112 // Declaration kinds for which the definition is not resolvable.
5113 case Decl::UnresolvedUsingTypename:
5114 case Decl::UnresolvedUsingValue:
5115 break;
5116
5117 case Decl::UsingDirective:
5118 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
5119 TU);
5120
5121 case Decl::NamespaceAlias:
5122 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
5123
5124 case Decl::Enum:
5125 case Decl::Record:
5126 case Decl::CXXRecord:
5127 case Decl::ClassTemplateSpecialization:
5128 case Decl::ClassTemplatePartialSpecialization:
5129 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
5130 return MakeCXCursor(Def, TU);
5131 return clang_getNullCursor();
5132
5133 case Decl::Function:
5134 case Decl::CXXMethod:
5135 case Decl::CXXConstructor:
5136 case Decl::CXXDestructor:
5137 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00005138 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005139 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00005140 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005141 return clang_getNullCursor();
5142 }
5143
Larisse Voufo39a1e502013-08-06 01:03:05 +00005144 case Decl::Var:
5145 case Decl::VarTemplateSpecialization:
5146 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00005147 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005148 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005149 return MakeCXCursor(Def, TU);
5150 return clang_getNullCursor();
5151 }
5152
5153 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00005154 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005155 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
5156 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
5157 return clang_getNullCursor();
5158 }
5159
5160 case Decl::ClassTemplate: {
5161 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
5162 ->getDefinition())
5163 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
5164 TU);
5165 return clang_getNullCursor();
5166 }
5167
Larisse Voufo39a1e502013-08-06 01:03:05 +00005168 case Decl::VarTemplate: {
5169 if (VarDecl *Def =
5170 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
5171 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
5172 return clang_getNullCursor();
5173 }
5174
Guy Benyei11169dd2012-12-18 14:30:41 +00005175 case Decl::Using:
5176 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
5177 D->getLocation(), TU);
5178
5179 case Decl::UsingShadow:
5180 return clang_getCursorDefinition(
5181 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
5182 TU));
5183
5184 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005185 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005186 if (Method->isThisDeclarationADefinition())
5187 return C;
5188
5189 // Dig out the method definition in the associated
5190 // @implementation, if we have it.
5191 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005192 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005193 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
5194 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
5195 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
5196 Method->isInstanceMethod()))
5197 if (Def->isThisDeclarationADefinition())
5198 return MakeCXCursor(Def, TU);
5199
5200 return clang_getNullCursor();
5201 }
5202
5203 case Decl::ObjCCategory:
5204 if (ObjCCategoryImplDecl *Impl
5205 = cast<ObjCCategoryDecl>(D)->getImplementation())
5206 return MakeCXCursor(Impl, TU);
5207 return clang_getNullCursor();
5208
5209 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005210 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005211 return MakeCXCursor(Def, TU);
5212 return clang_getNullCursor();
5213
5214 case Decl::ObjCInterface: {
5215 // There are two notions of a "definition" for an Objective-C
5216 // class: the interface and its implementation. When we resolved a
5217 // reference to an Objective-C class, produce the @interface as
5218 // the definition; when we were provided with the interface,
5219 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005220 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005221 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005222 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005223 return MakeCXCursor(Def, TU);
5224 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
5225 return MakeCXCursor(Impl, TU);
5226 return clang_getNullCursor();
5227 }
5228
5229 case Decl::ObjCProperty:
5230 // FIXME: We don't really know where to find the
5231 // ObjCPropertyImplDecls that implement this property.
5232 return clang_getNullCursor();
5233
5234 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005235 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005236 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005237 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005238 return MakeCXCursor(Def, TU);
5239
5240 return clang_getNullCursor();
5241
5242 case Decl::Friend:
5243 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
5244 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5245 return clang_getNullCursor();
5246
5247 case Decl::FriendTemplate:
5248 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
5249 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5250 return clang_getNullCursor();
5251 }
5252
5253 return clang_getNullCursor();
5254}
5255
5256unsigned clang_isCursorDefinition(CXCursor C) {
5257 if (!clang_isDeclaration(C.kind))
5258 return 0;
5259
5260 return clang_getCursorDefinition(C) == C;
5261}
5262
5263CXCursor clang_getCanonicalCursor(CXCursor C) {
5264 if (!clang_isDeclaration(C.kind))
5265 return C;
5266
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005267 if (const Decl *D = getCursorDecl(C)) {
5268 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005269 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5270 return MakeCXCursor(CatD, getCursorTU(C));
5271
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005272 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5273 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00005274 return MakeCXCursor(IFD, getCursorTU(C));
5275
5276 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5277 }
5278
5279 return C;
5280}
5281
5282int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5283 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5284}
5285
5286unsigned clang_getNumOverloadedDecls(CXCursor C) {
5287 if (C.kind != CXCursor_OverloadedDeclRef)
5288 return 0;
5289
5290 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005291 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005292 return E->getNumDecls();
5293
5294 if (OverloadedTemplateStorage *S
5295 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5296 return S->size();
5297
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005298 const Decl *D = Storage.get<const Decl *>();
5299 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005300 return Using->shadow_size();
5301
5302 return 0;
5303}
5304
5305CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5306 if (cursor.kind != CXCursor_OverloadedDeclRef)
5307 return clang_getNullCursor();
5308
5309 if (index >= clang_getNumOverloadedDecls(cursor))
5310 return clang_getNullCursor();
5311
5312 CXTranslationUnit TU = getCursorTU(cursor);
5313 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005314 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005315 return MakeCXCursor(E->decls_begin()[index], TU);
5316
5317 if (OverloadedTemplateStorage *S
5318 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5319 return MakeCXCursor(S->begin()[index], TU);
5320
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005321 const Decl *D = Storage.get<const Decl *>();
5322 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005323 // FIXME: This is, unfortunately, linear time.
5324 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5325 std::advance(Pos, index);
5326 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5327 }
5328
5329 return clang_getNullCursor();
5330}
5331
5332void clang_getDefinitionSpellingAndExtent(CXCursor C,
5333 const char **startBuf,
5334 const char **endBuf,
5335 unsigned *startLine,
5336 unsigned *startColumn,
5337 unsigned *endLine,
5338 unsigned *endColumn) {
5339 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005340 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005341 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5342
5343 SourceManager &SM = FD->getASTContext().getSourceManager();
5344 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5345 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5346 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5347 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5348 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5349 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5350}
5351
5352
5353CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5354 unsigned PieceIndex) {
5355 RefNamePieces Pieces;
5356
5357 switch (C.kind) {
5358 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005359 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005360 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5361 E->getQualifierLoc().getSourceRange());
5362 break;
5363
5364 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005365 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005366 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
5367 E->getQualifierLoc().getSourceRange(),
5368 E->getOptionalExplicitTemplateArgs());
5369 break;
5370
5371 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005372 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005373 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005374 const Expr *Callee = OCE->getCallee();
5375 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005376 Callee = ICE->getSubExpr();
5377
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005378 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005379 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5380 DRE->getQualifierLoc().getSourceRange());
5381 }
5382 break;
5383
5384 default:
5385 break;
5386 }
5387
5388 if (Pieces.empty()) {
5389 if (PieceIndex == 0)
5390 return clang_getCursorExtent(C);
5391 } else if (PieceIndex < Pieces.size()) {
5392 SourceRange R = Pieces[PieceIndex];
5393 if (R.isValid())
5394 return cxloc::translateSourceRange(getCursorContext(C), R);
5395 }
5396
5397 return clang_getNullRange();
5398}
5399
5400void clang_enableStackTraces(void) {
5401 llvm::sys::PrintStackTraceOnErrorSignal();
5402}
5403
5404void clang_executeOnThread(void (*fn)(void*), void *user_data,
5405 unsigned stack_size) {
5406 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5407}
5408
5409} // end: extern "C"
5410
5411//===----------------------------------------------------------------------===//
5412// Token-based Operations.
5413//===----------------------------------------------------------------------===//
5414
5415/* CXToken layout:
5416 * int_data[0]: a CXTokenKind
5417 * int_data[1]: starting token location
5418 * int_data[2]: token length
5419 * int_data[3]: reserved
5420 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5421 * otherwise unused.
5422 */
5423extern "C" {
5424
5425CXTokenKind clang_getTokenKind(CXToken CXTok) {
5426 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5427}
5428
5429CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5430 switch (clang_getTokenKind(CXTok)) {
5431 case CXToken_Identifier:
5432 case CXToken_Keyword:
5433 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005434 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005435 ->getNameStart());
5436
5437 case CXToken_Literal: {
5438 // We have stashed the starting pointer in the ptr_data field. Use it.
5439 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005440 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005441 }
5442
5443 case CXToken_Punctuation:
5444 case CXToken_Comment:
5445 break;
5446 }
5447
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005448 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005449 LOG_BAD_TU(TU);
5450 return cxstring::createEmpty();
5451 }
5452
Guy Benyei11169dd2012-12-18 14:30:41 +00005453 // We have to find the starting buffer pointer the hard way, by
5454 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005455 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005456 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005457 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005458
5459 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5460 std::pair<FileID, unsigned> LocInfo
5461 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5462 bool Invalid = false;
5463 StringRef Buffer
5464 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5465 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005466 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005467
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005468 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005469}
5470
5471CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005472 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005473 LOG_BAD_TU(TU);
5474 return clang_getNullLocation();
5475 }
5476
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005477 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005478 if (!CXXUnit)
5479 return clang_getNullLocation();
5480
5481 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5482 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5483}
5484
5485CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005486 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005487 LOG_BAD_TU(TU);
5488 return clang_getNullRange();
5489 }
5490
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005491 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005492 if (!CXXUnit)
5493 return clang_getNullRange();
5494
5495 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5496 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5497}
5498
5499static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5500 SmallVectorImpl<CXToken> &CXTokens) {
5501 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5502 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005503 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005504 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005505 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005506
5507 // Cannot tokenize across files.
5508 if (BeginLocInfo.first != EndLocInfo.first)
5509 return;
5510
5511 // Create a lexer
5512 bool Invalid = false;
5513 StringRef Buffer
5514 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5515 if (Invalid)
5516 return;
5517
5518 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5519 CXXUnit->getASTContext().getLangOpts(),
5520 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5521 Lex.SetCommentRetentionState(true);
5522
5523 // Lex tokens until we hit the end of the range.
5524 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5525 Token Tok;
5526 bool previousWasAt = false;
5527 do {
5528 // Lex the next token
5529 Lex.LexFromRawLexer(Tok);
5530 if (Tok.is(tok::eof))
5531 break;
5532
5533 // Initialize the CXToken.
5534 CXToken CXTok;
5535
5536 // - Common fields
5537 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5538 CXTok.int_data[2] = Tok.getLength();
5539 CXTok.int_data[3] = 0;
5540
5541 // - Kind-specific fields
5542 if (Tok.isLiteral()) {
5543 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005544 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005545 } else if (Tok.is(tok::raw_identifier)) {
5546 // Lookup the identifier to determine whether we have a keyword.
5547 IdentifierInfo *II
5548 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5549
5550 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5551 CXTok.int_data[0] = CXToken_Keyword;
5552 }
5553 else {
5554 CXTok.int_data[0] = Tok.is(tok::identifier)
5555 ? CXToken_Identifier
5556 : CXToken_Keyword;
5557 }
5558 CXTok.ptr_data = II;
5559 } else if (Tok.is(tok::comment)) {
5560 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005561 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005562 } else {
5563 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005564 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005565 }
5566 CXTokens.push_back(CXTok);
5567 previousWasAt = Tok.is(tok::at);
5568 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5569}
5570
5571void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5572 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005573 LOG_FUNC_SECTION {
5574 *Log << TU << ' ' << Range;
5575 }
5576
Guy Benyei11169dd2012-12-18 14:30:41 +00005577 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005578 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005579 if (NumTokens)
5580 *NumTokens = 0;
5581
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005582 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005583 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005584 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005585 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005586
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005587 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005588 if (!CXXUnit || !Tokens || !NumTokens)
5589 return;
5590
5591 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5592
5593 SourceRange R = cxloc::translateCXSourceRange(Range);
5594 if (R.isInvalid())
5595 return;
5596
5597 SmallVector<CXToken, 32> CXTokens;
5598 getTokens(CXXUnit, R, CXTokens);
5599
5600 if (CXTokens.empty())
5601 return;
5602
5603 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5604 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5605 *NumTokens = CXTokens.size();
5606}
5607
5608void clang_disposeTokens(CXTranslationUnit TU,
5609 CXToken *Tokens, unsigned NumTokens) {
5610 free(Tokens);
5611}
5612
5613} // end: extern "C"
5614
5615//===----------------------------------------------------------------------===//
5616// Token annotation APIs.
5617//===----------------------------------------------------------------------===//
5618
Guy Benyei11169dd2012-12-18 14:30:41 +00005619static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5620 CXCursor parent,
5621 CXClientData client_data);
5622static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5623 CXClientData client_data);
5624
5625namespace {
5626class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005627 CXToken *Tokens;
5628 CXCursor *Cursors;
5629 unsigned NumTokens;
5630 unsigned TokIdx;
5631 unsigned PreprocessingTokIdx;
5632 CursorVisitor AnnotateVis;
5633 SourceManager &SrcMgr;
5634 bool HasContextSensitiveKeywords;
5635
5636 struct PostChildrenInfo {
5637 CXCursor Cursor;
5638 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005639 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005640 unsigned BeforeChildrenTokenIdx;
5641 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005642 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005643
5644 CXToken &getTok(unsigned Idx) {
5645 assert(Idx < NumTokens);
5646 return Tokens[Idx];
5647 }
5648 const CXToken &getTok(unsigned Idx) const {
5649 assert(Idx < NumTokens);
5650 return Tokens[Idx];
5651 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005652 bool MoreTokens() const { return TokIdx < NumTokens; }
5653 unsigned NextToken() const { return TokIdx; }
5654 void AdvanceToken() { ++TokIdx; }
5655 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005656 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005657 }
5658 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005659 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005660 }
5661 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005662 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005663 }
5664
5665 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005666 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005667 SourceRange);
5668
5669public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005670 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005671 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005672 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005673 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005674 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005675 AnnotateTokensVisitor, this,
5676 /*VisitPreprocessorLast=*/true,
5677 /*VisitIncludedEntities=*/false,
5678 RegionOfInterest,
5679 /*VisitDeclsOnly=*/false,
5680 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005681 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005682 HasContextSensitiveKeywords(false) { }
5683
5684 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5685 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5686 bool postVisitChildren(CXCursor cursor);
5687 void AnnotateTokens();
5688
5689 /// \brief Determine whether the annotator saw any cursors that have
5690 /// context-sensitive keywords.
5691 bool hasContextSensitiveKeywords() const {
5692 return HasContextSensitiveKeywords;
5693 }
5694
5695 ~AnnotateTokensWorker() {
5696 assert(PostChildrenInfos.empty());
5697 }
5698};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00005699}
Guy Benyei11169dd2012-12-18 14:30:41 +00005700
5701void AnnotateTokensWorker::AnnotateTokens() {
5702 // Walk the AST within the region of interest, annotating tokens
5703 // along the way.
5704 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005705}
Guy Benyei11169dd2012-12-18 14:30:41 +00005706
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005707static inline void updateCursorAnnotation(CXCursor &Cursor,
5708 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005709 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005710 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005711 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005712}
5713
5714/// \brief It annotates and advances tokens with a cursor until the comparison
5715//// between the cursor location and the source range is the same as
5716/// \arg compResult.
5717///
5718/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5719/// Pass RangeOverlap to annotate tokens inside a range.
5720void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5721 RangeComparisonResult compResult,
5722 SourceRange range) {
5723 while (MoreTokens()) {
5724 const unsigned I = NextToken();
5725 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005726 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5727 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005728
5729 SourceLocation TokLoc = GetTokenLoc(I);
5730 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005731 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005732 AdvanceToken();
5733 continue;
5734 }
5735 break;
5736 }
5737}
5738
5739/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005740/// \returns true if it advanced beyond all macro tokens, false otherwise.
5741bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005742 CXCursor updateC,
5743 RangeComparisonResult compResult,
5744 SourceRange range) {
5745 assert(MoreTokens());
5746 assert(isFunctionMacroToken(NextToken()) &&
5747 "Should be called only for macro arg tokens");
5748
5749 // This works differently than annotateAndAdvanceTokens; because expanded
5750 // macro arguments can have arbitrary translation-unit source order, we do not
5751 // advance the token index one by one until a token fails the range test.
5752 // We only advance once past all of the macro arg tokens if all of them
5753 // pass the range test. If one of them fails we keep the token index pointing
5754 // at the start of the macro arg tokens so that the failing token will be
5755 // annotated by a subsequent annotation try.
5756
5757 bool atLeastOneCompFail = false;
5758
5759 unsigned I = NextToken();
5760 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5761 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5762 if (TokLoc.isFileID())
5763 continue; // not macro arg token, it's parens or comma.
5764 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5765 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5766 Cursors[I] = updateC;
5767 } else
5768 atLeastOneCompFail = true;
5769 }
5770
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005771 if (atLeastOneCompFail)
5772 return false;
5773
5774 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5775 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005776}
5777
5778enum CXChildVisitResult
5779AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005780 SourceRange cursorRange = getRawCursorExtent(cursor);
5781 if (cursorRange.isInvalid())
5782 return CXChildVisit_Recurse;
5783
5784 if (!HasContextSensitiveKeywords) {
5785 // Objective-C properties can have context-sensitive keywords.
5786 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005787 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005788 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5789 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5790 }
5791 // Objective-C methods can have context-sensitive keywords.
5792 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5793 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005794 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005795 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5796 if (Method->getObjCDeclQualifier())
5797 HasContextSensitiveKeywords = true;
5798 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005799 for (const auto *P : Method->params()) {
5800 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005801 HasContextSensitiveKeywords = true;
5802 break;
5803 }
5804 }
5805 }
5806 }
5807 }
5808 // C++ methods can have context-sensitive keywords.
5809 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005810 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005811 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5812 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5813 HasContextSensitiveKeywords = true;
5814 }
5815 }
5816 // C++ classes can have context-sensitive keywords.
5817 else if (cursor.kind == CXCursor_StructDecl ||
5818 cursor.kind == CXCursor_ClassDecl ||
5819 cursor.kind == CXCursor_ClassTemplate ||
5820 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005821 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005822 if (D->hasAttr<FinalAttr>())
5823 HasContextSensitiveKeywords = true;
5824 }
5825 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005826
5827 // Don't override a property annotation with its getter/setter method.
5828 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5829 parent.kind == CXCursor_ObjCPropertyDecl)
5830 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005831
5832 if (clang_isPreprocessing(cursor.kind)) {
5833 // Items in the preprocessing record are kept separate from items in
5834 // declarations, so we keep a separate token index.
5835 unsigned SavedTokIdx = TokIdx;
5836 TokIdx = PreprocessingTokIdx;
5837
5838 // Skip tokens up until we catch up to the beginning of the preprocessing
5839 // entry.
5840 while (MoreTokens()) {
5841 const unsigned I = NextToken();
5842 SourceLocation TokLoc = GetTokenLoc(I);
5843 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5844 case RangeBefore:
5845 AdvanceToken();
5846 continue;
5847 case RangeAfter:
5848 case RangeOverlap:
5849 break;
5850 }
5851 break;
5852 }
5853
5854 // Look at all of the tokens within this range.
5855 while (MoreTokens()) {
5856 const unsigned I = NextToken();
5857 SourceLocation TokLoc = GetTokenLoc(I);
5858 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5859 case RangeBefore:
5860 llvm_unreachable("Infeasible");
5861 case RangeAfter:
5862 break;
5863 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005864 // For macro expansions, just note where the beginning of the macro
5865 // expansion occurs.
5866 if (cursor.kind == CXCursor_MacroExpansion) {
5867 if (TokLoc == cursorRange.getBegin())
5868 Cursors[I] = cursor;
5869 AdvanceToken();
5870 break;
5871 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005872 // We may have already annotated macro names inside macro definitions.
5873 if (Cursors[I].kind != CXCursor_MacroExpansion)
5874 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005875 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005876 continue;
5877 }
5878 break;
5879 }
5880
5881 // Save the preprocessing token index; restore the non-preprocessing
5882 // token index.
5883 PreprocessingTokIdx = TokIdx;
5884 TokIdx = SavedTokIdx;
5885 return CXChildVisit_Recurse;
5886 }
5887
5888 if (cursorRange.isInvalid())
5889 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005890
5891 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005892 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005893 const enum CXCursorKind K = clang_getCursorKind(parent);
5894 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005895 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5896 // Attributes are annotated out-of-order, skip tokens until we reach it.
5897 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005898 ? clang_getNullCursor() : parent;
5899
5900 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5901
5902 // Avoid having the cursor of an expression "overwrite" the annotation of the
5903 // variable declaration that it belongs to.
5904 // This can happen for C++ constructor expressions whose range generally
5905 // include the variable declaration, e.g.:
5906 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005907 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005908 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005909 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005910 const unsigned I = NextToken();
5911 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5912 E->getLocStart() == D->getLocation() &&
5913 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005914 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005915 AdvanceToken();
5916 }
5917 }
5918 }
5919
5920 // Before recursing into the children keep some state that we are going
5921 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5922 // extra work after the child nodes are visited.
5923 // Note that we don't call VisitChildren here to avoid traversing statements
5924 // code-recursively which can blow the stack.
5925
5926 PostChildrenInfo Info;
5927 Info.Cursor = cursor;
5928 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005929 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005930 Info.BeforeChildrenTokenIdx = NextToken();
5931 PostChildrenInfos.push_back(Info);
5932
5933 return CXChildVisit_Recurse;
5934}
5935
5936bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5937 if (PostChildrenInfos.empty())
5938 return false;
5939 const PostChildrenInfo &Info = PostChildrenInfos.back();
5940 if (!clang_equalCursors(Info.Cursor, cursor))
5941 return false;
5942
5943 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5944 const unsigned AfterChildren = NextToken();
5945 SourceRange cursorRange = Info.CursorRange;
5946
5947 // Scan the tokens that are at the end of the cursor, but are not captured
5948 // but the child cursors.
5949 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5950
5951 // Scan the tokens that are at the beginning of the cursor, but are not
5952 // capture by the child cursors.
5953 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5954 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5955 break;
5956
5957 Cursors[I] = cursor;
5958 }
5959
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005960 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5961 // encountered the attribute cursor.
5962 if (clang_isAttribute(cursor.kind))
5963 TokIdx = Info.BeforeReachingCursorIdx;
5964
Guy Benyei11169dd2012-12-18 14:30:41 +00005965 PostChildrenInfos.pop_back();
5966 return false;
5967}
5968
5969static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5970 CXCursor parent,
5971 CXClientData client_data) {
5972 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5973}
5974
5975static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5976 CXClientData client_data) {
5977 return static_cast<AnnotateTokensWorker*>(client_data)->
5978 postVisitChildren(cursor);
5979}
5980
5981namespace {
5982
5983/// \brief Uses the macro expansions in the preprocessing record to find
5984/// and mark tokens that are macro arguments. This info is used by the
5985/// AnnotateTokensWorker.
5986class MarkMacroArgTokensVisitor {
5987 SourceManager &SM;
5988 CXToken *Tokens;
5989 unsigned NumTokens;
5990 unsigned CurIdx;
5991
5992public:
5993 MarkMacroArgTokensVisitor(SourceManager &SM,
5994 CXToken *tokens, unsigned numTokens)
5995 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5996
5997 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5998 if (cursor.kind != CXCursor_MacroExpansion)
5999 return CXChildVisit_Continue;
6000
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006001 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00006002 if (macroRange.getBegin() == macroRange.getEnd())
6003 return CXChildVisit_Continue; // it's not a function macro.
6004
6005 for (; CurIdx < NumTokens; ++CurIdx) {
6006 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
6007 macroRange.getBegin()))
6008 break;
6009 }
6010
6011 if (CurIdx == NumTokens)
6012 return CXChildVisit_Break;
6013
6014 for (; CurIdx < NumTokens; ++CurIdx) {
6015 SourceLocation tokLoc = getTokenLoc(CurIdx);
6016 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
6017 break;
6018
6019 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
6020 }
6021
6022 if (CurIdx == NumTokens)
6023 return CXChildVisit_Break;
6024
6025 return CXChildVisit_Continue;
6026 }
6027
6028private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006029 CXToken &getTok(unsigned Idx) {
6030 assert(Idx < NumTokens);
6031 return Tokens[Idx];
6032 }
6033 const CXToken &getTok(unsigned Idx) const {
6034 assert(Idx < NumTokens);
6035 return Tokens[Idx];
6036 }
6037
Guy Benyei11169dd2012-12-18 14:30:41 +00006038 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006039 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006040 }
6041
6042 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
6043 // The third field is reserved and currently not used. Use it here
6044 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006045 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00006046 }
6047};
6048
6049} // end anonymous namespace
6050
6051static CXChildVisitResult
6052MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
6053 CXClientData client_data) {
6054 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
6055 parent);
6056}
6057
6058namespace {
6059 struct clang_annotateTokens_Data {
6060 CXTranslationUnit TU;
6061 ASTUnit *CXXUnit;
6062 CXToken *Tokens;
6063 unsigned NumTokens;
6064 CXCursor *Cursors;
6065 };
6066}
6067
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006068/// \brief Used by \c annotatePreprocessorTokens.
6069/// \returns true if lexing was finished, false otherwise.
6070static bool lexNext(Lexer &Lex, Token &Tok,
6071 unsigned &NextIdx, unsigned NumTokens) {
6072 if (NextIdx >= NumTokens)
6073 return true;
6074
6075 ++NextIdx;
6076 Lex.LexFromRawLexer(Tok);
6077 if (Tok.is(tok::eof))
6078 return true;
6079
6080 return false;
6081}
6082
Guy Benyei11169dd2012-12-18 14:30:41 +00006083static void annotatePreprocessorTokens(CXTranslationUnit TU,
6084 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006085 CXCursor *Cursors,
6086 CXToken *Tokens,
6087 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006088 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006089
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006090 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00006091 SourceManager &SourceMgr = CXXUnit->getSourceManager();
6092 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006093 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00006094 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006095 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00006096
6097 if (BeginLocInfo.first != EndLocInfo.first)
6098 return;
6099
6100 StringRef Buffer;
6101 bool Invalid = false;
6102 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
6103 if (Buffer.empty() || Invalid)
6104 return;
6105
6106 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
6107 CXXUnit->getASTContext().getLangOpts(),
6108 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
6109 Buffer.end());
6110 Lex.SetCommentRetentionState(true);
6111
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006112 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006113 // Lex tokens in raw mode until we hit the end of the range, to avoid
6114 // entering #includes or expanding macros.
6115 while (true) {
6116 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006117 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6118 break;
6119 unsigned TokIdx = NextIdx-1;
6120 assert(Tok.getLocation() ==
6121 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006122
6123 reprocess:
6124 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006125 // We have found a preprocessing directive. Annotate the tokens
6126 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00006127 //
6128 // FIXME: Some simple tests here could identify macro definitions and
6129 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006130
6131 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006132 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6133 break;
6134
Craig Topper69186e72014-06-08 08:38:04 +00006135 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00006136 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006137 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6138 break;
6139
6140 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00006141 IdentifierInfo &II =
6142 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006143 SourceLocation MappedTokLoc =
6144 CXXUnit->mapLocationToPreamble(Tok.getLocation());
6145 MI = getMacroInfo(II, MappedTokLoc, TU);
6146 }
6147 }
6148
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006149 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00006150 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006151 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
6152 finished = true;
6153 break;
6154 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006155 // If we are in a macro definition, check if the token was ever a
6156 // macro name and annotate it if that's the case.
6157 if (MI) {
6158 SourceLocation SaveLoc = Tok.getLocation();
6159 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
Richard Smith66a81862015-05-04 02:25:31 +00006160 MacroDefinitionRecord *MacroDef =
6161 checkForMacroInMacroDefinition(MI, Tok, TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006162 Tok.setLocation(SaveLoc);
6163 if (MacroDef)
Richard Smith66a81862015-05-04 02:25:31 +00006164 Cursors[NextIdx - 1] =
6165 MakeMacroExpansionCursor(MacroDef, Tok.getLocation(), TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006166 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006167 } while (!Tok.isAtStartOfLine());
6168
6169 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
6170 assert(TokIdx <= LastIdx);
6171 SourceLocation EndLoc =
6172 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
6173 CXCursor Cursor =
6174 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
6175
6176 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006177 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006178
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006179 if (finished)
6180 break;
6181 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00006182 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006183 }
6184}
6185
6186// This gets run a separate thread to avoid stack blowout.
6187static void clang_annotateTokensImpl(void *UserData) {
6188 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
6189 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
6190 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
6191 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
6192 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
6193
Dmitri Gribenko183436e2013-01-26 21:49:50 +00006194 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006195 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
6196 setThreadBackgroundPriority();
6197
6198 // Determine the region of interest, which contains all of the tokens.
6199 SourceRange RegionOfInterest;
6200 RegionOfInterest.setBegin(
6201 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
6202 RegionOfInterest.setEnd(
6203 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
6204 Tokens[NumTokens-1])));
6205
Guy Benyei11169dd2012-12-18 14:30:41 +00006206 // Relex the tokens within the source range to look for preprocessing
6207 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006208 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006209
6210 // If begin location points inside a macro argument, set it to the expansion
6211 // location so we can have the full context when annotating semantically.
6212 {
6213 SourceManager &SM = CXXUnit->getSourceManager();
6214 SourceLocation Loc =
6215 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
6216 if (Loc.isMacroID())
6217 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
6218 }
6219
Guy Benyei11169dd2012-12-18 14:30:41 +00006220 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
6221 // Search and mark tokens that are macro argument expansions.
6222 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
6223 Tokens, NumTokens);
6224 CursorVisitor MacroArgMarker(TU,
6225 MarkMacroArgTokensVisitorDelegate, &Visitor,
6226 /*VisitPreprocessorLast=*/true,
6227 /*VisitIncludedEntities=*/false,
6228 RegionOfInterest);
6229 MacroArgMarker.visitPreprocessedEntitiesInRegion();
6230 }
6231
6232 // Annotate all of the source locations in the region of interest that map to
6233 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006234 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00006235
6236 // FIXME: We use a ridiculous stack size here because the data-recursion
6237 // algorithm uses a large stack frame than the non-data recursive version,
6238 // and AnnotationTokensWorker currently transforms the data-recursion
6239 // algorithm back into a traditional recursion by explicitly calling
6240 // VisitChildren(). We will need to remove this explicit recursive call.
6241 W.AnnotateTokens();
6242
6243 // If we ran into any entities that involve context-sensitive keywords,
6244 // take another pass through the tokens to mark them as such.
6245 if (W.hasContextSensitiveKeywords()) {
6246 for (unsigned I = 0; I != NumTokens; ++I) {
6247 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
6248 continue;
6249
6250 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
6251 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006252 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006253 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
6254 if (Property->getPropertyAttributesAsWritten() != 0 &&
6255 llvm::StringSwitch<bool>(II->getName())
6256 .Case("readonly", true)
6257 .Case("assign", true)
6258 .Case("unsafe_unretained", true)
6259 .Case("readwrite", true)
6260 .Case("retain", true)
6261 .Case("copy", true)
6262 .Case("nonatomic", true)
6263 .Case("atomic", true)
6264 .Case("getter", true)
6265 .Case("setter", true)
6266 .Case("strong", true)
6267 .Case("weak", true)
6268 .Default(false))
6269 Tokens[I].int_data[0] = CXToken_Keyword;
6270 }
6271 continue;
6272 }
6273
6274 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6275 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6276 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6277 if (llvm::StringSwitch<bool>(II->getName())
6278 .Case("in", true)
6279 .Case("out", true)
6280 .Case("inout", true)
6281 .Case("oneway", true)
6282 .Case("bycopy", true)
6283 .Case("byref", true)
6284 .Default(false))
6285 Tokens[I].int_data[0] = CXToken_Keyword;
6286 continue;
6287 }
6288
6289 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6290 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6291 Tokens[I].int_data[0] = CXToken_Keyword;
6292 continue;
6293 }
6294 }
6295 }
6296}
6297
6298extern "C" {
6299
6300void clang_annotateTokens(CXTranslationUnit TU,
6301 CXToken *Tokens, unsigned NumTokens,
6302 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006303 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006304 LOG_BAD_TU(TU);
6305 return;
6306 }
6307 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006308 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006309 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006310 }
6311
6312 LOG_FUNC_SECTION {
6313 *Log << TU << ' ';
6314 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6315 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6316 *Log << clang_getRange(bloc, eloc);
6317 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006318
6319 // Any token we don't specifically annotate will have a NULL cursor.
6320 CXCursor C = clang_getNullCursor();
6321 for (unsigned I = 0; I != NumTokens; ++I)
6322 Cursors[I] = C;
6323
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006324 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006325 if (!CXXUnit)
6326 return;
6327
6328 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
6329
6330 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
6331 llvm::CrashRecoveryContext CRC;
6332 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
6333 GetSafetyThreadStackSize() * 2)) {
6334 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6335 }
6336}
6337
6338} // end: extern "C"
6339
6340//===----------------------------------------------------------------------===//
6341// Operations for querying linkage of a cursor.
6342//===----------------------------------------------------------------------===//
6343
6344extern "C" {
6345CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6346 if (!clang_isDeclaration(cursor.kind))
6347 return CXLinkage_Invalid;
6348
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006349 const Decl *D = cxcursor::getCursorDecl(cursor);
6350 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006351 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006352 case NoLinkage:
6353 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006354 case InternalLinkage: return CXLinkage_Internal;
6355 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6356 case ExternalLinkage: return CXLinkage_External;
6357 };
6358
6359 return CXLinkage_Invalid;
6360}
6361} // end: extern "C"
6362
6363//===----------------------------------------------------------------------===//
6364// Operations for querying language of a cursor.
6365//===----------------------------------------------------------------------===//
6366
6367static CXLanguageKind getDeclLanguage(const Decl *D) {
6368 if (!D)
6369 return CXLanguage_C;
6370
6371 switch (D->getKind()) {
6372 default:
6373 break;
6374 case Decl::ImplicitParam:
6375 case Decl::ObjCAtDefsField:
6376 case Decl::ObjCCategory:
6377 case Decl::ObjCCategoryImpl:
6378 case Decl::ObjCCompatibleAlias:
6379 case Decl::ObjCImplementation:
6380 case Decl::ObjCInterface:
6381 case Decl::ObjCIvar:
6382 case Decl::ObjCMethod:
6383 case Decl::ObjCProperty:
6384 case Decl::ObjCPropertyImpl:
6385 case Decl::ObjCProtocol:
Douglas Gregor85f3f952015-07-07 03:57:15 +00006386 case Decl::ObjCTypeParam:
Guy Benyei11169dd2012-12-18 14:30:41 +00006387 return CXLanguage_ObjC;
6388 case Decl::CXXConstructor:
6389 case Decl::CXXConversion:
6390 case Decl::CXXDestructor:
6391 case Decl::CXXMethod:
6392 case Decl::CXXRecord:
6393 case Decl::ClassTemplate:
6394 case Decl::ClassTemplatePartialSpecialization:
6395 case Decl::ClassTemplateSpecialization:
6396 case Decl::Friend:
6397 case Decl::FriendTemplate:
6398 case Decl::FunctionTemplate:
6399 case Decl::LinkageSpec:
6400 case Decl::Namespace:
6401 case Decl::NamespaceAlias:
6402 case Decl::NonTypeTemplateParm:
6403 case Decl::StaticAssert:
6404 case Decl::TemplateTemplateParm:
6405 case Decl::TemplateTypeParm:
6406 case Decl::UnresolvedUsingTypename:
6407 case Decl::UnresolvedUsingValue:
6408 case Decl::Using:
6409 case Decl::UsingDirective:
6410 case Decl::UsingShadow:
6411 return CXLanguage_CPlusPlus;
6412 }
6413
6414 return CXLanguage_C;
6415}
6416
6417extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006418
6419static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6420 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
6421 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00006422
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006423 switch (D->getAvailability()) {
6424 case AR_Available:
6425 case AR_NotYetIntroduced:
6426 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006427 return getCursorAvailabilityForDecl(
6428 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006429 return CXAvailability_Available;
6430
6431 case AR_Deprecated:
6432 return CXAvailability_Deprecated;
6433
6434 case AR_Unavailable:
6435 return CXAvailability_NotAvailable;
6436 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006437
6438 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006439}
6440
Guy Benyei11169dd2012-12-18 14:30:41 +00006441enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6442 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006443 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6444 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006445
6446 return CXAvailability_Available;
6447}
6448
6449static CXVersion convertVersion(VersionTuple In) {
6450 CXVersion Out = { -1, -1, -1 };
6451 if (In.empty())
6452 return Out;
6453
6454 Out.Major = In.getMajor();
6455
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006456 Optional<unsigned> Minor = In.getMinor();
6457 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006458 Out.Minor = *Minor;
6459 else
6460 return Out;
6461
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006462 Optional<unsigned> Subminor = In.getSubminor();
6463 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006464 Out.Subminor = *Subminor;
6465
6466 return Out;
6467}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006468
6469static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6470 int *always_deprecated,
6471 CXString *deprecated_message,
6472 int *always_unavailable,
6473 CXString *unavailable_message,
6474 CXPlatformAvailability *availability,
6475 int availability_size) {
6476 bool HadAvailAttr = false;
6477 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006478 for (auto A : D->attrs()) {
6479 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006480 HadAvailAttr = true;
6481 if (always_deprecated)
6482 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006483 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006484 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006485 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006486 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006487 continue;
6488 }
6489
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006490 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006491 HadAvailAttr = true;
6492 if (always_unavailable)
6493 *always_unavailable = 1;
6494 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006495 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006496 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6497 }
6498 continue;
6499 }
6500
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006501 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006502 HadAvailAttr = true;
6503 if (N < availability_size) {
6504 availability[N].Platform
6505 = cxstring::createDup(Avail->getPlatform()->getName());
6506 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6507 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6508 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6509 availability[N].Unavailable = Avail->getUnavailable();
6510 availability[N].Message = cxstring::createDup(Avail->getMessage());
6511 }
6512 ++N;
6513 }
6514 }
6515
6516 if (!HadAvailAttr)
6517 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6518 return getCursorPlatformAvailabilityForDecl(
6519 cast<Decl>(EnumConst->getDeclContext()),
6520 always_deprecated,
6521 deprecated_message,
6522 always_unavailable,
6523 unavailable_message,
6524 availability,
6525 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006526
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006527 return N;
6528}
6529
Guy Benyei11169dd2012-12-18 14:30:41 +00006530int clang_getCursorPlatformAvailability(CXCursor cursor,
6531 int *always_deprecated,
6532 CXString *deprecated_message,
6533 int *always_unavailable,
6534 CXString *unavailable_message,
6535 CXPlatformAvailability *availability,
6536 int availability_size) {
6537 if (always_deprecated)
6538 *always_deprecated = 0;
6539 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006540 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006541 if (always_unavailable)
6542 *always_unavailable = 0;
6543 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006544 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006545
Guy Benyei11169dd2012-12-18 14:30:41 +00006546 if (!clang_isDeclaration(cursor.kind))
6547 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006548
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006549 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006550 if (!D)
6551 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006552
6553 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6554 deprecated_message,
6555 always_unavailable,
6556 unavailable_message,
6557 availability,
6558 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006559}
6560
6561void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6562 clang_disposeString(availability->Platform);
6563 clang_disposeString(availability->Message);
6564}
6565
6566CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6567 if (clang_isDeclaration(cursor.kind))
6568 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6569
6570 return CXLanguage_Invalid;
6571}
6572
6573 /// \brief If the given cursor is the "templated" declaration
6574 /// descibing a class or function template, return the class or
6575 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006576static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006577 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006578 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006579
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006580 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006581 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6582 return FunTmpl;
6583
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006584 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006585 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6586 return ClassTmpl;
6587
6588 return D;
6589}
6590
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006591
6592enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
6593 StorageClass sc = SC_None;
6594 const Decl *D = getCursorDecl(C);
6595 if (D) {
6596 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
6597 sc = FD->getStorageClass();
6598 } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
6599 sc = VD->getStorageClass();
6600 } else {
6601 return CX_SC_Invalid;
6602 }
6603 } else {
6604 return CX_SC_Invalid;
6605 }
6606 switch (sc) {
6607 case SC_None:
6608 return CX_SC_None;
6609 case SC_Extern:
6610 return CX_SC_Extern;
6611 case SC_Static:
6612 return CX_SC_Static;
6613 case SC_PrivateExtern:
6614 return CX_SC_PrivateExtern;
6615 case SC_OpenCLWorkGroupLocal:
6616 return CX_SC_OpenCLWorkGroupLocal;
6617 case SC_Auto:
6618 return CX_SC_Auto;
6619 case SC_Register:
6620 return CX_SC_Register;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006621 }
Kaelyn Takataab61e702014-10-15 18:03:26 +00006622 llvm_unreachable("Unhandled storage class!");
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006623}
6624
Guy Benyei11169dd2012-12-18 14:30:41 +00006625CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6626 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006627 if (const Decl *D = getCursorDecl(cursor)) {
6628 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006629 if (!DC)
6630 return clang_getNullCursor();
6631
6632 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6633 getCursorTU(cursor));
6634 }
6635 }
6636
6637 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006638 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006639 return MakeCXCursor(D, getCursorTU(cursor));
6640 }
6641
6642 return clang_getNullCursor();
6643}
6644
6645CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6646 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006647 if (const Decl *D = getCursorDecl(cursor)) {
6648 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006649 if (!DC)
6650 return clang_getNullCursor();
6651
6652 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6653 getCursorTU(cursor));
6654 }
6655 }
6656
6657 // FIXME: Note that we can't easily compute the lexical context of a
6658 // statement or expression, so we return nothing.
6659 return clang_getNullCursor();
6660}
6661
6662CXFile clang_getIncludedFile(CXCursor cursor) {
6663 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006664 return nullptr;
6665
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006666 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006667 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006668}
6669
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006670unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6671 if (C.kind != CXCursor_ObjCPropertyDecl)
6672 return CXObjCPropertyAttr_noattr;
6673
6674 unsigned Result = CXObjCPropertyAttr_noattr;
6675 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6676 ObjCPropertyDecl::PropertyAttributeKind Attr =
6677 PD->getPropertyAttributesAsWritten();
6678
6679#define SET_CXOBJCPROP_ATTR(A) \
6680 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6681 Result |= CXObjCPropertyAttr_##A
6682 SET_CXOBJCPROP_ATTR(readonly);
6683 SET_CXOBJCPROP_ATTR(getter);
6684 SET_CXOBJCPROP_ATTR(assign);
6685 SET_CXOBJCPROP_ATTR(readwrite);
6686 SET_CXOBJCPROP_ATTR(retain);
6687 SET_CXOBJCPROP_ATTR(copy);
6688 SET_CXOBJCPROP_ATTR(nonatomic);
6689 SET_CXOBJCPROP_ATTR(setter);
6690 SET_CXOBJCPROP_ATTR(atomic);
6691 SET_CXOBJCPROP_ATTR(weak);
6692 SET_CXOBJCPROP_ATTR(strong);
6693 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6694#undef SET_CXOBJCPROP_ATTR
6695
6696 return Result;
6697}
6698
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006699unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6700 if (!clang_isDeclaration(C.kind))
6701 return CXObjCDeclQualifier_None;
6702
6703 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6704 const Decl *D = getCursorDecl(C);
6705 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6706 QT = MD->getObjCDeclQualifier();
6707 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6708 QT = PD->getObjCDeclQualifier();
6709 if (QT == Decl::OBJC_TQ_None)
6710 return CXObjCDeclQualifier_None;
6711
6712 unsigned Result = CXObjCDeclQualifier_None;
6713 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6714 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6715 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6716 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6717 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6718 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6719
6720 return Result;
6721}
6722
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006723unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6724 if (!clang_isDeclaration(C.kind))
6725 return 0;
6726
6727 const Decl *D = getCursorDecl(C);
6728 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6729 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6730 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6731 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6732
6733 return 0;
6734}
6735
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006736unsigned clang_Cursor_isVariadic(CXCursor C) {
6737 if (!clang_isDeclaration(C.kind))
6738 return 0;
6739
6740 const Decl *D = getCursorDecl(C);
6741 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6742 return FD->isVariadic();
6743 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6744 return MD->isVariadic();
6745
6746 return 0;
6747}
6748
Guy Benyei11169dd2012-12-18 14:30:41 +00006749CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6750 if (!clang_isDeclaration(C.kind))
6751 return clang_getNullRange();
6752
6753 const Decl *D = getCursorDecl(C);
6754 ASTContext &Context = getCursorContext(C);
6755 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6756 if (!RC)
6757 return clang_getNullRange();
6758
6759 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6760}
6761
6762CXString clang_Cursor_getRawCommentText(CXCursor C) {
6763 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006764 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006765
6766 const Decl *D = getCursorDecl(C);
6767 ASTContext &Context = getCursorContext(C);
6768 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6769 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6770 StringRef();
6771
6772 // Don't duplicate the string because RawText points directly into source
6773 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006774 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006775}
6776
6777CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6778 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006779 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006780
6781 const Decl *D = getCursorDecl(C);
6782 const ASTContext &Context = getCursorContext(C);
6783 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6784
6785 if (RC) {
6786 StringRef BriefText = RC->getBriefText(Context);
6787
6788 // Don't duplicate the string because RawComment ensures that this memory
6789 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006790 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006791 }
6792
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006793 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006794}
6795
Guy Benyei11169dd2012-12-18 14:30:41 +00006796CXModule clang_Cursor_getModule(CXCursor C) {
6797 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006798 if (const ImportDecl *ImportD =
6799 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006800 return ImportD->getImportedModule();
6801 }
6802
Craig Topper69186e72014-06-08 08:38:04 +00006803 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006804}
6805
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006806CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6807 if (isNotUsableTU(TU)) {
6808 LOG_BAD_TU(TU);
6809 return nullptr;
6810 }
6811 if (!File)
6812 return nullptr;
6813 FileEntry *FE = static_cast<FileEntry *>(File);
6814
6815 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6816 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6817 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6818
Richard Smithfeb54b62014-10-23 02:01:19 +00006819 return Header.getModule();
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006820}
6821
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006822CXFile clang_Module_getASTFile(CXModule CXMod) {
6823 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006824 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006825 Module *Mod = static_cast<Module*>(CXMod);
6826 return const_cast<FileEntry *>(Mod->getASTFile());
6827}
6828
Guy Benyei11169dd2012-12-18 14:30:41 +00006829CXModule clang_Module_getParent(CXModule CXMod) {
6830 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006831 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006832 Module *Mod = static_cast<Module*>(CXMod);
6833 return Mod->Parent;
6834}
6835
6836CXString clang_Module_getName(CXModule CXMod) {
6837 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006838 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006839 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006840 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006841}
6842
6843CXString clang_Module_getFullName(CXModule CXMod) {
6844 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006845 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006846 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006847 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006848}
6849
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006850int clang_Module_isSystem(CXModule CXMod) {
6851 if (!CXMod)
6852 return 0;
6853 Module *Mod = static_cast<Module*>(CXMod);
6854 return Mod->IsSystem;
6855}
6856
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006857unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6858 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006859 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006860 LOG_BAD_TU(TU);
6861 return 0;
6862 }
6863 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006864 return 0;
6865 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006866 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6867 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6868 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006869}
6870
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006871CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6872 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006873 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006874 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006875 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006876 }
6877 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006878 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006879 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006880 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006881
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006882 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6883 if (Index < TopHeaders.size())
6884 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006885
Craig Topper69186e72014-06-08 08:38:04 +00006886 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006887}
6888
6889} // end: extern "C"
6890
6891//===----------------------------------------------------------------------===//
6892// C++ AST instrospection.
6893//===----------------------------------------------------------------------===//
6894
6895extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006896unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6897 if (!clang_isDeclaration(C.kind))
6898 return 0;
6899
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006900 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006901 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006902 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006903 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6904}
6905
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006906unsigned clang_CXXMethod_isConst(CXCursor C) {
6907 if (!clang_isDeclaration(C.kind))
6908 return 0;
6909
6910 const Decl *D = cxcursor::getCursorDecl(C);
6911 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006912 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006913 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6914}
6915
Guy Benyei11169dd2012-12-18 14:30:41 +00006916unsigned clang_CXXMethod_isStatic(CXCursor C) {
6917 if (!clang_isDeclaration(C.kind))
6918 return 0;
6919
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006920 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006921 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006922 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006923 return (Method && Method->isStatic()) ? 1 : 0;
6924}
6925
6926unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6927 if (!clang_isDeclaration(C.kind))
6928 return 0;
6929
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006930 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006931 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006932 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006933 return (Method && Method->isVirtual()) ? 1 : 0;
6934}
6935} // end: extern "C"
6936
6937//===----------------------------------------------------------------------===//
6938// Attribute introspection.
6939//===----------------------------------------------------------------------===//
6940
6941extern "C" {
6942CXType clang_getIBOutletCollectionType(CXCursor C) {
6943 if (C.kind != CXCursor_IBOutletCollectionAttr)
6944 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6945
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006946 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006947 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6948
6949 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6950}
6951} // end: extern "C"
6952
6953//===----------------------------------------------------------------------===//
6954// Inspecting memory usage.
6955//===----------------------------------------------------------------------===//
6956
6957typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6958
6959static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6960 enum CXTUResourceUsageKind k,
6961 unsigned long amount) {
6962 CXTUResourceUsageEntry entry = { k, amount };
6963 entries.push_back(entry);
6964}
6965
6966extern "C" {
6967
6968const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6969 const char *str = "";
6970 switch (kind) {
6971 case CXTUResourceUsage_AST:
6972 str = "ASTContext: expressions, declarations, and types";
6973 break;
6974 case CXTUResourceUsage_Identifiers:
6975 str = "ASTContext: identifiers";
6976 break;
6977 case CXTUResourceUsage_Selectors:
6978 str = "ASTContext: selectors";
6979 break;
6980 case CXTUResourceUsage_GlobalCompletionResults:
6981 str = "Code completion: cached global results";
6982 break;
6983 case CXTUResourceUsage_SourceManagerContentCache:
6984 str = "SourceManager: content cache allocator";
6985 break;
6986 case CXTUResourceUsage_AST_SideTables:
6987 str = "ASTContext: side tables";
6988 break;
6989 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6990 str = "SourceManager: malloc'ed memory buffers";
6991 break;
6992 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6993 str = "SourceManager: mmap'ed memory buffers";
6994 break;
6995 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6996 str = "ExternalASTSource: malloc'ed memory buffers";
6997 break;
6998 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6999 str = "ExternalASTSource: mmap'ed memory buffers";
7000 break;
7001 case CXTUResourceUsage_Preprocessor:
7002 str = "Preprocessor: malloc'ed memory";
7003 break;
7004 case CXTUResourceUsage_PreprocessingRecord:
7005 str = "Preprocessor: PreprocessingRecord";
7006 break;
7007 case CXTUResourceUsage_SourceManager_DataStructures:
7008 str = "SourceManager: data structures and tables";
7009 break;
7010 case CXTUResourceUsage_Preprocessor_HeaderSearch:
7011 str = "Preprocessor: header search tables";
7012 break;
7013 }
7014 return str;
7015}
7016
7017CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007018 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007019 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00007020 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00007021 return usage;
7022 }
7023
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007024 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00007025 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00007026 ASTContext &astContext = astUnit->getASTContext();
7027
7028 // How much memory is used by AST nodes and types?
7029 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
7030 (unsigned long) astContext.getASTAllocatedMemory());
7031
7032 // How much memory is used by identifiers?
7033 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
7034 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
7035
7036 // How much memory is used for selectors?
7037 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
7038 (unsigned long) astContext.Selectors.getTotalMemory());
7039
7040 // How much memory is used by ASTContext's side tables?
7041 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
7042 (unsigned long) astContext.getSideTableAllocatedMemory());
7043
7044 // How much memory is used for caching global code completion results?
7045 unsigned long completionBytes = 0;
7046 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00007047 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007048 completionBytes = completionAllocator->getTotalMemory();
7049 }
7050 createCXTUResourceUsageEntry(*entries,
7051 CXTUResourceUsage_GlobalCompletionResults,
7052 completionBytes);
7053
7054 // How much memory is being used by SourceManager's content cache?
7055 createCXTUResourceUsageEntry(*entries,
7056 CXTUResourceUsage_SourceManagerContentCache,
7057 (unsigned long) astContext.getSourceManager().getContentCacheSize());
7058
7059 // How much memory is being used by the MemoryBuffer's in SourceManager?
7060 const SourceManager::MemoryBufferSizes &srcBufs =
7061 astUnit->getSourceManager().getMemoryBufferSizes();
7062
7063 createCXTUResourceUsageEntry(*entries,
7064 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
7065 (unsigned long) srcBufs.malloc_bytes);
7066 createCXTUResourceUsageEntry(*entries,
7067 CXTUResourceUsage_SourceManager_Membuffer_MMap,
7068 (unsigned long) srcBufs.mmap_bytes);
7069 createCXTUResourceUsageEntry(*entries,
7070 CXTUResourceUsage_SourceManager_DataStructures,
7071 (unsigned long) astContext.getSourceManager()
7072 .getDataStructureSizes());
7073
7074 // How much memory is being used by the ExternalASTSource?
7075 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
7076 const ExternalASTSource::MemoryBufferSizes &sizes =
7077 esrc->getMemoryBufferSizes();
7078
7079 createCXTUResourceUsageEntry(*entries,
7080 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
7081 (unsigned long) sizes.malloc_bytes);
7082 createCXTUResourceUsageEntry(*entries,
7083 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
7084 (unsigned long) sizes.mmap_bytes);
7085 }
7086
7087 // How much memory is being used by the Preprocessor?
7088 Preprocessor &pp = astUnit->getPreprocessor();
7089 createCXTUResourceUsageEntry(*entries,
7090 CXTUResourceUsage_Preprocessor,
7091 pp.getTotalMemory());
7092
7093 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
7094 createCXTUResourceUsageEntry(*entries,
7095 CXTUResourceUsage_PreprocessingRecord,
7096 pRec->getTotalMemory());
7097 }
7098
7099 createCXTUResourceUsageEntry(*entries,
7100 CXTUResourceUsage_Preprocessor_HeaderSearch,
7101 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00007102
Guy Benyei11169dd2012-12-18 14:30:41 +00007103 CXTUResourceUsage usage = { (void*) entries.get(),
7104 (unsigned) entries->size(),
Alexander Kornienko6ee521c2015-01-23 15:36:10 +00007105 !entries->empty() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00007106 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00007107 return usage;
7108}
7109
7110void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
7111 if (usage.data)
7112 delete (MemUsageEntries*) usage.data;
7113}
7114
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007115CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
7116 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007117 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00007118 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007119
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007120 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007121 LOG_BAD_TU(TU);
7122 return skipped;
7123 }
7124
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007125 if (!file)
7126 return skipped;
7127
7128 ASTUnit *astUnit = cxtu::getASTUnit(TU);
7129 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
7130 if (!ppRec)
7131 return skipped;
7132
7133 ASTContext &Ctx = astUnit->getASTContext();
7134 SourceManager &sm = Ctx.getSourceManager();
7135 FileEntry *fileEntry = static_cast<FileEntry *>(file);
7136 FileID wantedFileID = sm.translateFile(fileEntry);
7137
7138 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
7139 std::vector<SourceRange> wantedRanges;
7140 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
7141 i != ei; ++i) {
7142 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
7143 wantedRanges.push_back(*i);
7144 }
7145
7146 skipped->count = wantedRanges.size();
7147 skipped->ranges = new CXSourceRange[skipped->count];
7148 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
7149 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
7150
7151 return skipped;
7152}
7153
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007154void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
7155 if (ranges) {
7156 delete[] ranges->ranges;
7157 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007158 }
7159}
7160
Guy Benyei11169dd2012-12-18 14:30:41 +00007161} // end extern "C"
7162
7163void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
7164 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
7165 for (unsigned I = 0; I != Usage.numEntries; ++I)
7166 fprintf(stderr, " %s: %lu\n",
7167 clang_getTUResourceUsageName(Usage.entries[I].kind),
7168 Usage.entries[I].amount);
7169
7170 clang_disposeCXTUResourceUsage(Usage);
7171}
7172
7173//===----------------------------------------------------------------------===//
7174// Misc. utility functions.
7175//===----------------------------------------------------------------------===//
7176
7177/// Default to using an 8 MB stack size on "safety" threads.
7178static unsigned SafetyStackThreadSize = 8 << 20;
7179
7180namespace clang {
7181
7182bool RunSafely(llvm::CrashRecoveryContext &CRC,
7183 void (*Fn)(void*), void *UserData,
7184 unsigned Size) {
7185 if (!Size)
7186 Size = GetSafetyThreadStackSize();
7187 if (Size)
7188 return CRC.RunSafelyOnThread(Fn, UserData, Size);
7189 return CRC.RunSafely(Fn, UserData);
7190}
7191
7192unsigned GetSafetyThreadStackSize() {
7193 return SafetyStackThreadSize;
7194}
7195
7196void SetSafetyThreadStackSize(unsigned Value) {
7197 SafetyStackThreadSize = Value;
7198}
7199
Alexander Kornienkoab9db512015-06-22 23:07:51 +00007200}
Guy Benyei11169dd2012-12-18 14:30:41 +00007201
7202void clang::setThreadBackgroundPriority() {
7203 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
7204 return;
7205
Alp Toker1a86ad22014-07-06 06:24:00 +00007206#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00007207 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
7208#endif
7209}
7210
7211void cxindex::printDiagsToStderr(ASTUnit *Unit) {
7212 if (!Unit)
7213 return;
7214
7215 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
7216 DEnd = Unit->stored_diag_end();
7217 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00007218 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00007219 CXString Msg = clang_formatDiagnostic(&Diag,
7220 clang_defaultDiagnosticDisplayOptions());
7221 fprintf(stderr, "%s\n", clang_getCString(Msg));
7222 clang_disposeString(Msg);
7223 }
7224#ifdef LLVM_ON_WIN32
7225 // On Windows, force a flush, since there may be multiple copies of
7226 // stderr and stdout in the file system, all with different buffers
7227 // but writing to the same device.
7228 fflush(stderr);
7229#endif
7230}
7231
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007232MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
7233 SourceLocation MacroDefLoc,
7234 CXTranslationUnit TU){
7235 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007236 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007237 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007238 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007239
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007240 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007241 Preprocessor &PP = Unit->getPreprocessor();
Richard Smith20e883e2015-04-29 23:20:19 +00007242 MacroDirective *MD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007243 if (MD) {
7244 for (MacroDirective::DefInfo
7245 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
7246 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
7247 return Def.getMacroInfo();
7248 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007249 }
7250
Craig Topper69186e72014-06-08 08:38:04 +00007251 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007252}
7253
Richard Smith66a81862015-05-04 02:25:31 +00007254const MacroInfo *cxindex::getMacroInfo(const MacroDefinitionRecord *MacroDef,
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007255 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007256 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007257 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007258 const IdentifierInfo *II = MacroDef->getName();
7259 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00007260 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007261
7262 return getMacroInfo(*II, MacroDef->getLocation(), TU);
7263}
7264
Richard Smith66a81862015-05-04 02:25:31 +00007265MacroDefinitionRecord *
7266cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, const Token &Tok,
7267 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007268 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007269 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007270 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00007271 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007272
7273 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007274 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007275 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
7276 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007277 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007278
7279 // Check that the token is inside the definition and not its argument list.
7280 SourceManager &SM = Unit->getSourceManager();
7281 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00007282 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007283 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00007284 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007285
7286 Preprocessor &PP = Unit->getPreprocessor();
7287 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
7288 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00007289 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007290
Alp Toker2d57cea2014-05-17 04:53:25 +00007291 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007292 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007293 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007294
7295 // Check that the identifier is not one of the macro arguments.
7296 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00007297 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007298
Richard Smith20e883e2015-04-29 23:20:19 +00007299 MacroDirective *InnerMD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007300 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00007301 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007302
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007303 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007304}
7305
Richard Smith66a81862015-05-04 02:25:31 +00007306MacroDefinitionRecord *
7307cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, SourceLocation Loc,
7308 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007309 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007310 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007311
7312 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007313 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007314 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007315 Preprocessor &PP = Unit->getPreprocessor();
7316 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00007317 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007318 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7319 Token Tok;
7320 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00007321 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007322
7323 return checkForMacroInMacroDefinition(MI, Tok, TU);
7324}
7325
Guy Benyei11169dd2012-12-18 14:30:41 +00007326extern "C" {
7327
7328CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007329 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00007330}
7331
7332} // end: extern "C"
7333
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007334Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7335 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007336 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007337 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007338 if (Unit->isMainFileAST())
7339 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007340 return *this;
7341 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007342 } else {
7343 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007344 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007345 return *this;
7346}
7347
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007348Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7349 *this << FE->getName();
7350 return *this;
7351}
7352
7353Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7354 CXString cursorName = clang_getCursorDisplayName(cursor);
7355 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7356 clang_disposeString(cursorName);
7357 return *this;
7358}
7359
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007360Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7361 CXFile File;
7362 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007363 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007364 CXString FileName = clang_getFileName(File);
7365 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7366 clang_disposeString(FileName);
7367 return *this;
7368}
7369
7370Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7371 CXSourceLocation BLoc = clang_getRangeStart(range);
7372 CXSourceLocation ELoc = clang_getRangeEnd(range);
7373
7374 CXFile BFile;
7375 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007376 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007377
7378 CXFile EFile;
7379 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007380 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007381
7382 CXString BFileName = clang_getFileName(BFile);
7383 if (BFile == EFile) {
7384 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7385 BLine, BColumn, ELine, EColumn);
7386 } else {
7387 CXString EFileName = clang_getFileName(EFile);
7388 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7389 BLine, BColumn)
7390 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7391 ELine, EColumn);
7392 clang_disposeString(EFileName);
7393 }
7394 clang_disposeString(BFileName);
7395 return *this;
7396}
7397
7398Logger &cxindex::Logger::operator<<(CXString Str) {
7399 *this << clang_getCString(Str);
7400 return *this;
7401}
7402
7403Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7404 LogOS << Fmt;
7405 return *this;
7406}
7407
Chandler Carruth37ad2582014-06-27 15:14:39 +00007408static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7409
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007410cxindex::Logger::~Logger() {
7411 LogOS.flush();
7412
Chandler Carruth37ad2582014-06-27 15:14:39 +00007413 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007414
7415 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7416
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007417 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007418 OS << "[libclang:" << Name << ':';
7419
Alp Toker1a86ad22014-07-06 06:24:00 +00007420#ifdef USE_DARWIN_THREADS
7421 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007422 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7423 OS << tid << ':';
7424#endif
7425
7426 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7427 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
Yaron Keren09fb7c62015-03-10 07:33:23 +00007428 OS << Msg << '\n';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007429
7430 if (Trace) {
Zachary Turner1fe2a8d2015-03-05 19:15:09 +00007431 llvm::sys::PrintStackTrace(OS);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007432 OS << "--------------------------------------------------\n";
7433 }
7434}