blob: 49b9da23865aab9efcac56bed10b42d34ec71151 [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
3105 if (NumErrors != Diags->getClient()->getNumErrors()) {
3106 // Make sure to check that 'Unit' is non-NULL.
3107 if (CXXIdx->getDisplayDiagnostics())
3108 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
3109 }
3110
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003111 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
3112 PTUI->result = CXError_ASTReadError;
3113 } else {
Ahmed Charles9a16beb2014-03-07 19:33:25 +00003114 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003115 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
3116 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003117}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003118
3119CXTranslationUnit
3120clang_parseTranslationUnit(CXIndex CIdx,
3121 const char *source_filename,
3122 const char *const *command_line_args,
3123 int num_command_line_args,
3124 struct CXUnsavedFile *unsaved_files,
3125 unsigned num_unsaved_files,
3126 unsigned options) {
3127 CXTranslationUnit TU;
3128 enum CXErrorCode Result = clang_parseTranslationUnit2(
3129 CIdx, source_filename, command_line_args, num_command_line_args,
3130 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00003131 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003132 assert((TU && Result == CXError_Success) ||
3133 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003134 return TU;
3135}
3136
3137enum CXErrorCode clang_parseTranslationUnit2(
3138 CXIndex CIdx,
3139 const char *source_filename,
3140 const char *const *command_line_args,
3141 int num_command_line_args,
3142 struct CXUnsavedFile *unsaved_files,
3143 unsigned num_unsaved_files,
3144 unsigned options,
3145 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003146 LOG_FUNC_SECTION {
3147 *Log << source_filename << ": ";
3148 for (int i = 0; i != num_command_line_args; ++i)
3149 *Log << command_line_args[i] << " ";
3150 }
3151
Alp Toker9d85b182014-07-07 01:23:14 +00003152 if (num_unsaved_files && !unsaved_files)
3153 return CXError_InvalidArguments;
3154
Alp Toker5c532982014-07-07 22:42:03 +00003155 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00003156 ParseTranslationUnitInfo PTUI = {
3157 CIdx,
3158 source_filename,
3159 command_line_args,
3160 num_command_line_args,
3161 llvm::makeArrayRef(unsaved_files, num_unsaved_files),
3162 options,
3163 out_TU,
Alp Toker5c532982014-07-07 22:42:03 +00003164 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00003165 llvm::CrashRecoveryContext CRC;
3166
3167 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
3168 fprintf(stderr, "libclang: crash detected during parsing: {\n");
3169 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3170 fprintf(stderr, " 'command_line_args' : [");
3171 for (int i = 0; i != num_command_line_args; ++i) {
3172 if (i)
3173 fprintf(stderr, ", ");
3174 fprintf(stderr, "'%s'", command_line_args[i]);
3175 }
3176 fprintf(stderr, "],\n");
3177 fprintf(stderr, " 'unsaved_files' : [");
3178 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3179 if (i)
3180 fprintf(stderr, ", ");
3181 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3182 unsaved_files[i].Length);
3183 }
3184 fprintf(stderr, "],\n");
3185 fprintf(stderr, " 'options' : %d,\n", options);
3186 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003187
3188 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003189 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003190 if (CXTranslationUnit *TU = PTUI.out_TU)
3191 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003192 }
Alp Toker5c532982014-07-07 22:42:03 +00003193
3194 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003195}
3196
3197unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
3198 return CXSaveTranslationUnit_None;
3199}
3200
3201namespace {
3202
3203struct SaveTranslationUnitInfo {
3204 CXTranslationUnit TU;
3205 const char *FileName;
3206 unsigned options;
3207 CXSaveError result;
3208};
3209
3210}
3211
3212static void clang_saveTranslationUnit_Impl(void *UserData) {
3213 SaveTranslationUnitInfo *STUI =
3214 static_cast<SaveTranslationUnitInfo*>(UserData);
3215
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003216 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003217 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3218 setThreadBackgroundPriority();
3219
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003220 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00003221 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
3222}
3223
3224int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3225 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003226 LOG_FUNC_SECTION {
3227 *Log << TU << ' ' << FileName;
3228 }
3229
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003230 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003231 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003232 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003233 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003234
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003235 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003236 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3237 if (!CXXUnit->hasSema())
3238 return CXSaveError_InvalidTU;
3239
3240 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
3241
3242 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3243 getenv("LIBCLANG_NOTHREADS")) {
3244 clang_saveTranslationUnit_Impl(&STUI);
3245
3246 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3247 PrintLibclangResourceUsage(TU);
3248
3249 return STUI.result;
3250 }
3251
3252 // We have an AST that has invalid nodes due to compiler errors.
3253 // Use a crash recovery thread for protection.
3254
3255 llvm::CrashRecoveryContext CRC;
3256
3257 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
3258 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3259 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3260 fprintf(stderr, " 'options' : %d,\n", options);
3261 fprintf(stderr, "}\n");
3262
3263 return CXSaveError_Unknown;
3264
3265 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3266 PrintLibclangResourceUsage(TU);
3267 }
3268
3269 return STUI.result;
3270}
3271
3272void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3273 if (CTUnit) {
3274 // If the translation unit has been marked as unsafe to free, just discard
3275 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003276 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3277 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003278 return;
3279
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003280 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003281 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003282 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3283 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003284 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003285 delete CTUnit;
3286 }
3287}
3288
3289unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3290 return CXReparse_None;
3291}
3292
3293struct ReparseTranslationUnitInfo {
3294 CXTranslationUnit TU;
Alp Toker9d85b182014-07-07 01:23:14 +00003295 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00003296 unsigned options;
Alp Toker5c532982014-07-07 22:42:03 +00003297 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003298};
3299
3300static void clang_reparseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00003301 const ReparseTranslationUnitInfo *RTUI =
3302 static_cast<ReparseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00003303 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003304 unsigned options = RTUI->options;
3305 (void) options;
3306
3307 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003308 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003309 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003310 RTUI->result = CXError_InvalidArguments;
3311 return;
3312 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003313
3314 // Reset the associated diagnostics.
3315 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003316 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003317
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003318 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003319 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3320 setThreadBackgroundPriority();
3321
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003322 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003323 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003324
3325 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3326 new std::vector<ASTUnit::RemappedFile>());
3327
Guy Benyei11169dd2012-12-18 14:30:41 +00003328 // Recover resources if we crash before exiting this function.
3329 llvm::CrashRecoveryContextCleanupRegistrar<
3330 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003331
3332 for (auto &UF : RTUI->unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003333 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003334 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003335 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003336 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003337
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003338 if (!CXXUnit->Reparse(CXXIdx->getPCHContainerOperations(),
3339 *RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003340 RTUI->result = CXError_Success;
3341 else if (isASTReadError(CXXUnit))
3342 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003343}
3344
3345int clang_reparseTranslationUnit(CXTranslationUnit TU,
3346 unsigned num_unsaved_files,
3347 struct CXUnsavedFile *unsaved_files,
3348 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003349 LOG_FUNC_SECTION {
3350 *Log << TU;
3351 }
3352
Alp Toker9d85b182014-07-07 01:23:14 +00003353 if (num_unsaved_files && !unsaved_files)
3354 return CXError_InvalidArguments;
3355
Alp Toker5c532982014-07-07 22:42:03 +00003356 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00003357 ReparseTranslationUnitInfo RTUI = {
3358 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options,
Alp Toker5c532982014-07-07 22:42:03 +00003359 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00003360
3361 if (getenv("LIBCLANG_NOTHREADS")) {
3362 clang_reparseTranslationUnit_Impl(&RTUI);
Alp Toker5c532982014-07-07 22:42:03 +00003363 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003364 }
3365
3366 llvm::CrashRecoveryContext CRC;
3367
3368 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3369 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003370 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003371 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003372 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3373 PrintLibclangResourceUsage(TU);
3374
Alp Toker5c532982014-07-07 22:42:03 +00003375 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003376}
3377
3378
3379CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003380 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003381 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003382 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003383 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003384
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003385 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003386 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003387}
3388
3389CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003390 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003391 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003392 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003393 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003394
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003395 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003396 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3397}
3398
3399} // end: extern "C"
3400
3401//===----------------------------------------------------------------------===//
3402// CXFile Operations.
3403//===----------------------------------------------------------------------===//
3404
3405extern "C" {
3406CXString clang_getFileName(CXFile SFile) {
3407 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003408 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003409
3410 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003411 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003412}
3413
3414time_t clang_getFileTime(CXFile SFile) {
3415 if (!SFile)
3416 return 0;
3417
3418 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3419 return FEnt->getModificationTime();
3420}
3421
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003422CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003423 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003424 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003425 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003426 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003427
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003428 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003429
3430 FileManager &FMgr = CXXUnit->getFileManager();
3431 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3432}
3433
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003434unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3435 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003436 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003437 LOG_BAD_TU(TU);
3438 return 0;
3439 }
3440
3441 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003442 return 0;
3443
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003444 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003445 FileEntry *FEnt = static_cast<FileEntry *>(file);
3446 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3447 .isFileMultipleIncludeGuarded(FEnt);
3448}
3449
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003450int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3451 if (!file || !outID)
3452 return 1;
3453
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003454 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003455 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3456 outID->data[0] = ID.getDevice();
3457 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003458 outID->data[2] = FEnt->getModificationTime();
3459 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003460}
3461
Argyrios Kyrtzidisac3997e2014-08-16 00:26:19 +00003462int clang_File_isEqual(CXFile file1, CXFile file2) {
3463 if (file1 == file2)
3464 return true;
3465
3466 if (!file1 || !file2)
3467 return false;
3468
3469 FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
3470 FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
3471 return FEnt1->getUniqueID() == FEnt2->getUniqueID();
3472}
3473
Guy Benyei11169dd2012-12-18 14:30:41 +00003474} // end: extern "C"
3475
3476//===----------------------------------------------------------------------===//
3477// CXCursor Operations.
3478//===----------------------------------------------------------------------===//
3479
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003480static const Decl *getDeclFromExpr(const Stmt *E) {
3481 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003482 return getDeclFromExpr(CE->getSubExpr());
3483
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003484 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003485 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003486 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003487 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003488 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003489 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003490 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003491 if (PRE->isExplicitProperty())
3492 return PRE->getExplicitProperty();
3493 // It could be messaging both getter and setter as in:
3494 // ++myobj.myprop;
3495 // in which case prefer to associate the setter since it is less obvious
3496 // from inspecting the source that the setter is going to get called.
3497 if (PRE->isMessagingSetter())
3498 return PRE->getImplicitPropertySetter();
3499 return PRE->getImplicitPropertyGetter();
3500 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003501 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003502 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003503 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003504 if (Expr *Src = OVE->getSourceExpr())
3505 return getDeclFromExpr(Src);
3506
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003507 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003508 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003509 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003510 if (!CE->isElidable())
3511 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003512 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003513 return OME->getMethodDecl();
3514
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003515 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003516 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003517 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003518 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3519 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003520 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003521 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3522 isa<ParmVarDecl>(SizeOfPack->getPack()))
3523 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003524
3525 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003526}
3527
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003528static SourceLocation getLocationFromExpr(const Expr *E) {
3529 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003530 return getLocationFromExpr(CE->getSubExpr());
3531
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003532 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003533 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003534 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003535 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003536 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003537 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003538 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003539 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003540 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003541 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003542 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003543 return PropRef->getLocation();
3544
3545 return E->getLocStart();
3546}
3547
3548extern "C" {
3549
3550unsigned clang_visitChildren(CXCursor parent,
3551 CXCursorVisitor visitor,
3552 CXClientData client_data) {
3553 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3554 /*VisitPreprocessorLast=*/false);
3555 return CursorVis.VisitChildren(parent);
3556}
3557
3558#ifndef __has_feature
3559#define __has_feature(x) 0
3560#endif
3561#if __has_feature(blocks)
3562typedef enum CXChildVisitResult
3563 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3564
3565static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3566 CXClientData client_data) {
3567 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3568 return block(cursor, parent);
3569}
3570#else
3571// If we are compiled with a compiler that doesn't have native blocks support,
3572// define and call the block manually, so the
3573typedef struct _CXChildVisitResult
3574{
3575 void *isa;
3576 int flags;
3577 int reserved;
3578 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3579 CXCursor);
3580} *CXCursorVisitorBlock;
3581
3582static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3583 CXClientData client_data) {
3584 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3585 return block->invoke(block, cursor, parent);
3586}
3587#endif
3588
3589
3590unsigned clang_visitChildrenWithBlock(CXCursor parent,
3591 CXCursorVisitorBlock block) {
3592 return clang_visitChildren(parent, visitWithBlock, block);
3593}
3594
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003595static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003596 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003597 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003598
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003599 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003600 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003601 if (const ObjCPropertyImplDecl *PropImpl =
3602 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003603 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003604 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003605
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003606 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003607 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003608 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003609
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003610 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003611 }
3612
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003613 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003614 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003615
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003616 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003617 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3618 // and returns different names. NamedDecl returns the class name and
3619 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003620 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003621
3622 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003623 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003624
3625 SmallString<1024> S;
3626 llvm::raw_svector_ostream os(S);
3627 ND->printName(os);
3628
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003629 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003630}
3631
3632CXString clang_getCursorSpelling(CXCursor C) {
3633 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003634 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003635
3636 if (clang_isReference(C.kind)) {
3637 switch (C.kind) {
3638 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003639 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003640 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003641 }
3642 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003643 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003644 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003645 }
3646 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003647 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003648 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003649 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003650 }
3651 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003652 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003653 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003654 }
3655 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003656 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003657 assert(Type && "Missing type decl");
3658
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003659 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003660 getAsString());
3661 }
3662 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003663 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003664 assert(Template && "Missing template decl");
3665
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003666 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003667 }
3668
3669 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003670 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003671 assert(NS && "Missing namespace decl");
3672
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003673 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003674 }
3675
3676 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003677 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003678 assert(Field && "Missing member decl");
3679
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003680 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003681 }
3682
3683 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003684 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003685 assert(Label && "Missing label");
3686
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003687 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003688 }
3689
3690 case CXCursor_OverloadedDeclRef: {
3691 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003692 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3693 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003694 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003695 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003696 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003697 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003698 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003699 OverloadedTemplateStorage *Ovl
3700 = Storage.get<OverloadedTemplateStorage*>();
3701 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003702 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003703 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003704 }
3705
3706 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003707 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003708 assert(Var && "Missing variable decl");
3709
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003710 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003711 }
3712
3713 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003714 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003715 }
3716 }
3717
3718 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003719 const Expr *E = getCursorExpr(C);
3720
3721 if (C.kind == CXCursor_ObjCStringLiteral ||
3722 C.kind == CXCursor_StringLiteral) {
3723 const StringLiteral *SLit;
3724 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3725 SLit = OSL->getString();
3726 } else {
3727 SLit = cast<StringLiteral>(E);
3728 }
3729 SmallString<256> Buf;
3730 llvm::raw_svector_ostream OS(Buf);
3731 SLit->outputString(OS);
3732 return cxstring::createDup(OS.str());
3733 }
3734
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003735 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003736 if (D)
3737 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003738 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003739 }
3740
3741 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003742 const Stmt *S = getCursorStmt(C);
3743 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003744 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003745
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003746 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003747 }
3748
3749 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003750 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003751 ->getNameStart());
3752
3753 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003754 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003755 ->getNameStart());
3756
3757 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003758 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003759
3760 if (clang_isDeclaration(C.kind))
3761 return getDeclSpelling(getCursorDecl(C));
3762
3763 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003764 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003765 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003766 }
3767
3768 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003769 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003770 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003771 }
3772
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003773 if (C.kind == CXCursor_PackedAttr) {
3774 return cxstring::createRef("packed");
3775 }
3776
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003777 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003778}
3779
3780CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3781 unsigned pieceIndex,
3782 unsigned options) {
3783 if (clang_Cursor_isNull(C))
3784 return clang_getNullRange();
3785
3786 ASTContext &Ctx = getCursorContext(C);
3787
3788 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003789 const Stmt *S = getCursorStmt(C);
3790 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003791 if (pieceIndex > 0)
3792 return clang_getNullRange();
3793 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3794 }
3795
3796 return clang_getNullRange();
3797 }
3798
3799 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003800 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003801 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3802 if (pieceIndex >= ME->getNumSelectorLocs())
3803 return clang_getNullRange();
3804 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3805 }
3806 }
3807
3808 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3809 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003810 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003811 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3812 if (pieceIndex >= MD->getNumSelectorLocs())
3813 return clang_getNullRange();
3814 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3815 }
3816 }
3817
3818 if (C.kind == CXCursor_ObjCCategoryDecl ||
3819 C.kind == CXCursor_ObjCCategoryImplDecl) {
3820 if (pieceIndex > 0)
3821 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003822 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003823 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3824 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003825 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003826 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3827 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3828 }
3829
3830 if (C.kind == CXCursor_ModuleImportDecl) {
3831 if (pieceIndex > 0)
3832 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003833 if (const ImportDecl *ImportD =
3834 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003835 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3836 if (!Locs.empty())
3837 return cxloc::translateSourceRange(Ctx,
3838 SourceRange(Locs.front(), Locs.back()));
3839 }
3840 return clang_getNullRange();
3841 }
3842
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00003843 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
3844 C.kind == CXCursor_ConversionFunction) {
3845 if (pieceIndex > 0)
3846 return clang_getNullRange();
3847 if (const FunctionDecl *FD =
3848 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
3849 DeclarationNameInfo FunctionName = FD->getNameInfo();
3850 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
3851 }
3852 return clang_getNullRange();
3853 }
3854
Guy Benyei11169dd2012-12-18 14:30:41 +00003855 // FIXME: A CXCursor_InclusionDirective should give the location of the
3856 // filename, but we don't keep track of this.
3857
3858 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3859 // but we don't keep track of this.
3860
3861 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3862 // but we don't keep track of this.
3863
3864 // Default handling, give the location of the cursor.
3865
3866 if (pieceIndex > 0)
3867 return clang_getNullRange();
3868
3869 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3870 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3871 return cxloc::translateSourceRange(Ctx, Loc);
3872}
3873
Eli Bendersky44a206f2014-07-31 18:04:56 +00003874CXString clang_Cursor_getMangling(CXCursor C) {
3875 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
3876 return cxstring::createEmpty();
3877
Eli Bendersky44a206f2014-07-31 18:04:56 +00003878 // Mangling only works for functions and variables.
Eli Bendersky79759592014-08-01 15:01:10 +00003879 const Decl *D = getCursorDecl(C);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003880 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
3881 return cxstring::createEmpty();
3882
Eli Bendersky79759592014-08-01 15:01:10 +00003883 // First apply frontend mangling.
Eli Bendersky44a206f2014-07-31 18:04:56 +00003884 const NamedDecl *ND = cast<NamedDecl>(D);
Eli Bendersky79759592014-08-01 15:01:10 +00003885 ASTContext &Ctx = ND->getASTContext();
3886 std::unique_ptr<MangleContext> MC(Ctx.createMangleContext());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003887
Eli Bendersky79759592014-08-01 15:01:10 +00003888 std::string FrontendBuf;
3889 llvm::raw_string_ostream FrontendBufOS(FrontendBuf);
3890 MC->mangleName(ND, FrontendBufOS);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003891
Eli Bendersky79759592014-08-01 15:01:10 +00003892 // Now apply backend mangling.
3893 std::unique_ptr<llvm::DataLayout> DL(
3894 new llvm::DataLayout(Ctx.getTargetInfo().getTargetDescription()));
Eli Bendersky79759592014-08-01 15:01:10 +00003895
3896 std::string FinalBuf;
3897 llvm::raw_string_ostream FinalBufOS(FinalBuf);
Rafael Espindolab633d202015-06-23 13:59:36 +00003898 llvm::Mangler::getNameWithPrefix(FinalBufOS, llvm::Twine(FrontendBufOS.str()),
3899 *DL);
Eli Bendersky79759592014-08-01 15:01:10 +00003900
3901 return cxstring::createDup(FinalBufOS.str());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003902}
3903
Guy Benyei11169dd2012-12-18 14:30:41 +00003904CXString clang_getCursorDisplayName(CXCursor C) {
3905 if (!clang_isDeclaration(C.kind))
3906 return clang_getCursorSpelling(C);
3907
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003908 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003909 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003910 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003911
3912 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003913 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003914 D = FunTmpl->getTemplatedDecl();
3915
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003916 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003917 SmallString<64> Str;
3918 llvm::raw_svector_ostream OS(Str);
3919 OS << *Function;
3920 if (Function->getPrimaryTemplate())
3921 OS << "<>";
3922 OS << "(";
3923 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3924 if (I)
3925 OS << ", ";
3926 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3927 }
3928
3929 if (Function->isVariadic()) {
3930 if (Function->getNumParams())
3931 OS << ", ";
3932 OS << "...";
3933 }
3934 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003935 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003936 }
3937
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003938 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003939 SmallString<64> Str;
3940 llvm::raw_svector_ostream OS(Str);
3941 OS << *ClassTemplate;
3942 OS << "<";
3943 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3944 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3945 if (I)
3946 OS << ", ";
3947
3948 NamedDecl *Param = Params->getParam(I);
3949 if (Param->getIdentifier()) {
3950 OS << Param->getIdentifier()->getName();
3951 continue;
3952 }
3953
3954 // There is no parameter name, which makes this tricky. Try to come up
3955 // with something useful that isn't too long.
3956 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3957 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3958 else if (NonTypeTemplateParmDecl *NTTP
3959 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3960 OS << NTTP->getType().getAsString(Policy);
3961 else
3962 OS << "template<...> class";
3963 }
3964
3965 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003966 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003967 }
3968
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003969 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003970 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3971 // If the type was explicitly written, use that.
3972 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003973 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003974
Benjamin Kramer9170e912013-02-22 15:46:01 +00003975 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003976 llvm::raw_svector_ostream OS(Str);
3977 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003978 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003979 ClassSpec->getTemplateArgs().data(),
3980 ClassSpec->getTemplateArgs().size(),
3981 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003982 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003983 }
3984
3985 return clang_getCursorSpelling(C);
3986}
3987
3988CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3989 switch (Kind) {
3990 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003991 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003992 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003993 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003994 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003995 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003996 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003997 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003998 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003999 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004000 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004001 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004002 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004003 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004004 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004005 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004006 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004007 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004008 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004009 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004010 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004011 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004012 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004013 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004014 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004015 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004016 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004017 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004018 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004019 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004020 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004021 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004022 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004023 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004024 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004025 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004026 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004027 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004028 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004029 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00004030 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004031 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004032 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004033 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004034 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004035 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004036 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004037 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004038 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004039 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004040 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004041 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004042 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004043 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004044 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004045 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004046 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004047 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004048 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004049 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004050 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004051 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004052 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004053 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004054 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004055 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004056 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004057 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004058 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004059 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004060 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004061 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004062 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004063 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004064 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004065 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004066 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004067 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004068 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004069 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004070 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004071 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004072 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004073 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004074 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004075 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004076 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004077 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004078 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004079 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004080 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004081 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004082 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004083 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004084 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004085 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004086 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004087 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004088 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004089 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004090 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004091 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004092 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004093 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004094 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004095 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004096 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004097 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004098 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004099 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004100 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004101 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004102 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004103 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004104 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004105 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004106 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004107 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004108 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004109 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004110 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004111 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004112 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004113 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004114 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004115 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004116 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004117 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00004118 case CXCursor_ObjCSelfExpr:
4119 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004120 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004121 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004122 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004123 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004124 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004125 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004126 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004127 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004128 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004129 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004130 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004131 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004132 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004133 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004134 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004135 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004136 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004137 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004138 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004139 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004140 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004141 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004142 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004143 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004144 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004145 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004146 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004147 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004148 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004149 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004150 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004151 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004152 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004153 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004154 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004155 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004156 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004157 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004158 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004159 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004160 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004161 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004162 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004163 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004164 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004165 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004166 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004167 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004168 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004169 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004170 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004171 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004172 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004173 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004174 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004175 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004176 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004177 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004178 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004179 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004180 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004181 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004182 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004183 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004184 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004185 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004186 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004187 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004188 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004189 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004190 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004191 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004192 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004193 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004194 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004195 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004196 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004197 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004198 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004199 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004200 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004201 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004202 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004203 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004204 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004205 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004206 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004207 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00004208 case CXCursor_SEHLeaveStmt:
4209 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004210 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004211 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004212 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004213 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00004214 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004215 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00004216 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004217 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00004218 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004219 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00004220 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004221 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00004222 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004223 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004224 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004225 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004226 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004227 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004228 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004229 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004230 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004231 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004232 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004233 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004234 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004235 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004236 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004237 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004238 case CXCursor_PackedAttr:
4239 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00004240 case CXCursor_PureAttr:
4241 return cxstring::createRef("attribute(pure)");
4242 case CXCursor_ConstAttr:
4243 return cxstring::createRef("attribute(const)");
4244 case CXCursor_NoDuplicateAttr:
4245 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00004246 case CXCursor_CUDAConstantAttr:
4247 return cxstring::createRef("attribute(constant)");
4248 case CXCursor_CUDADeviceAttr:
4249 return cxstring::createRef("attribute(device)");
4250 case CXCursor_CUDAGlobalAttr:
4251 return cxstring::createRef("attribute(global)");
4252 case CXCursor_CUDAHostAttr:
4253 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00004254 case CXCursor_CUDASharedAttr:
4255 return cxstring::createRef("attribute(shared)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004256 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004257 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004258 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004259 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00004260 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004261 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004262 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004263 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004264 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004265 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00004266 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004267 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00004268 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004269 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004270 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004271 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004272 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004273 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004274 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004275 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004276 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004277 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004278 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004279 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004280 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004281 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004282 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004283 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004284 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004285 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004286 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004287 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004288 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004289 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004290 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004291 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004292 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004293 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004294 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004295 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004296 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004297 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004298 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004299 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004300 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004301 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004302 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004303 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004304 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004305 return cxstring::createRef("OMPParallelDirective");
4306 case CXCursor_OMPSimdDirective:
4307 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004308 case CXCursor_OMPForDirective:
4309 return cxstring::createRef("OMPForDirective");
Alexander Musmanf82886e2014-09-18 05:12:34 +00004310 case CXCursor_OMPForSimdDirective:
4311 return cxstring::createRef("OMPForSimdDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004312 case CXCursor_OMPSectionsDirective:
4313 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004314 case CXCursor_OMPSectionDirective:
4315 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004316 case CXCursor_OMPSingleDirective:
4317 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004318 case CXCursor_OMPMasterDirective:
4319 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004320 case CXCursor_OMPCriticalDirective:
4321 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004322 case CXCursor_OMPParallelForDirective:
4323 return cxstring::createRef("OMPParallelForDirective");
Alexander Musmane4e893b2014-09-23 09:33:00 +00004324 case CXCursor_OMPParallelForSimdDirective:
4325 return cxstring::createRef("OMPParallelForSimdDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004326 case CXCursor_OMPParallelSectionsDirective:
4327 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004328 case CXCursor_OMPTaskDirective:
4329 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004330 case CXCursor_OMPTaskyieldDirective:
4331 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004332 case CXCursor_OMPBarrierDirective:
4333 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004334 case CXCursor_OMPTaskwaitDirective:
4335 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00004336 case CXCursor_OMPTaskgroupDirective:
4337 return cxstring::createRef("OMPTaskgroupDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00004338 case CXCursor_OMPFlushDirective:
4339 return cxstring::createRef("OMPFlushDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004340 case CXCursor_OMPOrderedDirective:
4341 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00004342 case CXCursor_OMPAtomicDirective:
4343 return cxstring::createRef("OMPAtomicDirective");
Alexey Bataev0bd520b2014-09-19 08:19:49 +00004344 case CXCursor_OMPTargetDirective:
4345 return cxstring::createRef("OMPTargetDirective");
Alexey Bataev13314bf2014-10-09 04:18:56 +00004346 case CXCursor_OMPTeamsDirective:
4347 return cxstring::createRef("OMPTeamsDirective");
Alexey Bataev6d4ed052015-07-01 06:57:41 +00004348 case CXCursor_OMPCancellationPointDirective:
4349 return cxstring::createRef("OMPCancellationPointDirective");
Alexey Bataev80909872015-07-02 11:25:17 +00004350 case CXCursor_OMPCancelDirective:
4351 return cxstring::createRef("OMPCancelDirective");
Francisco Lopes da Silva975a9f62015-01-21 16:24:11 +00004352 case CXCursor_OverloadCandidate:
4353 return cxstring::createRef("OverloadCandidate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004354 }
4355
4356 llvm_unreachable("Unhandled CXCursorKind");
4357}
4358
4359struct GetCursorData {
4360 SourceLocation TokenBeginLoc;
4361 bool PointsAtMacroArgExpansion;
4362 bool VisitedObjCPropertyImplDecl;
4363 SourceLocation VisitedDeclaratorDeclStartLoc;
4364 CXCursor &BestCursor;
4365
4366 GetCursorData(SourceManager &SM,
4367 SourceLocation tokenBegin, CXCursor &outputCursor)
4368 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4369 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4370 VisitedObjCPropertyImplDecl = false;
4371 }
4372};
4373
4374static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4375 CXCursor parent,
4376 CXClientData client_data) {
4377 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4378 CXCursor *BestCursor = &Data->BestCursor;
4379
4380 // If we point inside a macro argument we should provide info of what the
4381 // token is so use the actual cursor, don't replace it with a macro expansion
4382 // cursor.
4383 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4384 return CXChildVisit_Recurse;
4385
4386 if (clang_isDeclaration(cursor.kind)) {
4387 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004388 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004389 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4390 if (MD->isImplicit())
4391 return CXChildVisit_Break;
4392
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004393 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004394 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4395 // Check that when we have multiple @class references in the same line,
4396 // that later ones do not override the previous ones.
4397 // If we have:
4398 // @class Foo, Bar;
4399 // source ranges for both start at '@', so 'Bar' will end up overriding
4400 // 'Foo' even though the cursor location was at 'Foo'.
4401 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4402 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004403 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004404 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4405 if (PrevID != ID &&
4406 !PrevID->isThisDeclarationADefinition() &&
4407 !ID->isThisDeclarationADefinition())
4408 return CXChildVisit_Break;
4409 }
4410
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004411 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004412 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4413 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4414 // Check that when we have multiple declarators in the same line,
4415 // that later ones do not override the previous ones.
4416 // If we have:
4417 // int Foo, Bar;
4418 // source ranges for both start at 'int', so 'Bar' will end up overriding
4419 // 'Foo' even though the cursor location was at 'Foo'.
4420 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4421 return CXChildVisit_Break;
4422 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4423
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004424 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004425 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4426 (void)PropImp;
4427 // Check that when we have multiple @synthesize in the same line,
4428 // that later ones do not override the previous ones.
4429 // If we have:
4430 // @synthesize Foo, Bar;
4431 // source ranges for both start at '@', so 'Bar' will end up overriding
4432 // 'Foo' even though the cursor location was at 'Foo'.
4433 if (Data->VisitedObjCPropertyImplDecl)
4434 return CXChildVisit_Break;
4435 Data->VisitedObjCPropertyImplDecl = true;
4436 }
4437 }
4438
4439 if (clang_isExpression(cursor.kind) &&
4440 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004441 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004442 // Avoid having the cursor of an expression replace the declaration cursor
4443 // when the expression source range overlaps the declaration range.
4444 // This can happen for C++ constructor expressions whose range generally
4445 // include the variable declaration, e.g.:
4446 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4447 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4448 D->getLocation() == Data->TokenBeginLoc)
4449 return CXChildVisit_Break;
4450 }
4451 }
4452
4453 // If our current best cursor is the construction of a temporary object,
4454 // don't replace that cursor with a type reference, because we want
4455 // clang_getCursor() to point at the constructor.
4456 if (clang_isExpression(BestCursor->kind) &&
4457 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4458 cursor.kind == CXCursor_TypeRef) {
4459 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4460 // as having the actual point on the type reference.
4461 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4462 return CXChildVisit_Recurse;
4463 }
Douglas Gregore9d95f12015-07-07 03:57:35 +00004464
4465 // If we already have an Objective-C superclass reference, don't
4466 // update it further.
4467 if (BestCursor->kind == CXCursor_ObjCSuperClassRef)
4468 return CXChildVisit_Break;
4469
Guy Benyei11169dd2012-12-18 14:30:41 +00004470 *BestCursor = cursor;
4471 return CXChildVisit_Recurse;
4472}
4473
4474CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004475 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004476 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004477 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004478 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004479
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004480 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004481 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4482
4483 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4484 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4485
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004486 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004487 CXFile SearchFile;
4488 unsigned SearchLine, SearchColumn;
4489 CXFile ResultFile;
4490 unsigned ResultLine, ResultColumn;
4491 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4492 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4493 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004494
4495 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4496 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004497 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004498 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004499 SearchFileName = clang_getFileName(SearchFile);
4500 ResultFileName = clang_getFileName(ResultFile);
4501 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4502 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004503 *Log << llvm::format("(%s:%d:%d) = %s",
4504 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4505 clang_getCString(KindSpelling))
4506 << llvm::format("(%s:%d:%d):%s%s",
4507 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4508 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004509 clang_disposeString(SearchFileName);
4510 clang_disposeString(ResultFileName);
4511 clang_disposeString(KindSpelling);
4512 clang_disposeString(USR);
4513
4514 CXCursor Definition = clang_getCursorDefinition(Result);
4515 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4516 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4517 CXString DefinitionKindSpelling
4518 = clang_getCursorKindSpelling(Definition.kind);
4519 CXFile DefinitionFile;
4520 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004521 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004522 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004523 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004524 *Log << llvm::format(" -> %s(%s:%d:%d)",
4525 clang_getCString(DefinitionKindSpelling),
4526 clang_getCString(DefinitionFileName),
4527 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004528 clang_disposeString(DefinitionFileName);
4529 clang_disposeString(DefinitionKindSpelling);
4530 }
4531 }
4532
4533 return Result;
4534}
4535
4536CXCursor clang_getNullCursor(void) {
4537 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4538}
4539
4540unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004541 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4542 // can't set consistently. For example, when visiting a DeclStmt we will set
4543 // it but we don't set it on the result of clang_getCursorDefinition for
4544 // a reference of the same declaration.
4545 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4546 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4547 // to provide that kind of info.
4548 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004549 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004550 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004551 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004552
Guy Benyei11169dd2012-12-18 14:30:41 +00004553 return X == Y;
4554}
4555
4556unsigned clang_hashCursor(CXCursor C) {
4557 unsigned Index = 0;
4558 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4559 Index = 1;
4560
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004561 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004562 std::make_pair(C.kind, C.data[Index]));
4563}
4564
4565unsigned clang_isInvalid(enum CXCursorKind K) {
4566 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4567}
4568
4569unsigned clang_isDeclaration(enum CXCursorKind K) {
4570 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4571 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4572}
4573
4574unsigned clang_isReference(enum CXCursorKind K) {
4575 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4576}
4577
4578unsigned clang_isExpression(enum CXCursorKind K) {
4579 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4580}
4581
4582unsigned clang_isStatement(enum CXCursorKind K) {
4583 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4584}
4585
4586unsigned clang_isAttribute(enum CXCursorKind K) {
4587 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4588}
4589
4590unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4591 return K == CXCursor_TranslationUnit;
4592}
4593
4594unsigned clang_isPreprocessing(enum CXCursorKind K) {
4595 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4596}
4597
4598unsigned clang_isUnexposed(enum CXCursorKind K) {
4599 switch (K) {
4600 case CXCursor_UnexposedDecl:
4601 case CXCursor_UnexposedExpr:
4602 case CXCursor_UnexposedStmt:
4603 case CXCursor_UnexposedAttr:
4604 return true;
4605 default:
4606 return false;
4607 }
4608}
4609
4610CXCursorKind clang_getCursorKind(CXCursor C) {
4611 return C.kind;
4612}
4613
4614CXSourceLocation clang_getCursorLocation(CXCursor C) {
4615 if (clang_isReference(C.kind)) {
4616 switch (C.kind) {
4617 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004618 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004619 = getCursorObjCSuperClassRef(C);
4620 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4621 }
4622
4623 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004624 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004625 = getCursorObjCProtocolRef(C);
4626 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4627 }
4628
4629 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004630 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004631 = getCursorObjCClassRef(C);
4632 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4633 }
4634
4635 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004636 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004637 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4638 }
4639
4640 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004641 std::pair<const TemplateDecl *, SourceLocation> P =
4642 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004643 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4644 }
4645
4646 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004647 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004648 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4649 }
4650
4651 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004652 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004653 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4654 }
4655
4656 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004657 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004658 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4659 }
4660
4661 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004662 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004663 if (!BaseSpec)
4664 return clang_getNullLocation();
4665
4666 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4667 return cxloc::translateSourceLocation(getCursorContext(C),
4668 TSInfo->getTypeLoc().getBeginLoc());
4669
4670 return cxloc::translateSourceLocation(getCursorContext(C),
4671 BaseSpec->getLocStart());
4672 }
4673
4674 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004675 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004676 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4677 }
4678
4679 case CXCursor_OverloadedDeclRef:
4680 return cxloc::translateSourceLocation(getCursorContext(C),
4681 getCursorOverloadedDeclRef(C).second);
4682
4683 default:
4684 // FIXME: Need a way to enumerate all non-reference cases.
4685 llvm_unreachable("Missed a reference kind");
4686 }
4687 }
4688
4689 if (clang_isExpression(C.kind))
4690 return cxloc::translateSourceLocation(getCursorContext(C),
4691 getLocationFromExpr(getCursorExpr(C)));
4692
4693 if (clang_isStatement(C.kind))
4694 return cxloc::translateSourceLocation(getCursorContext(C),
4695 getCursorStmt(C)->getLocStart());
4696
4697 if (C.kind == CXCursor_PreprocessingDirective) {
4698 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4699 return cxloc::translateSourceLocation(getCursorContext(C), L);
4700 }
4701
4702 if (C.kind == CXCursor_MacroExpansion) {
4703 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004704 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004705 return cxloc::translateSourceLocation(getCursorContext(C), L);
4706 }
4707
4708 if (C.kind == CXCursor_MacroDefinition) {
4709 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4710 return cxloc::translateSourceLocation(getCursorContext(C), L);
4711 }
4712
4713 if (C.kind == CXCursor_InclusionDirective) {
4714 SourceLocation L
4715 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4716 return cxloc::translateSourceLocation(getCursorContext(C), L);
4717 }
4718
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004719 if (clang_isAttribute(C.kind)) {
4720 SourceLocation L
4721 = cxcursor::getCursorAttr(C)->getLocation();
4722 return cxloc::translateSourceLocation(getCursorContext(C), L);
4723 }
4724
Guy Benyei11169dd2012-12-18 14:30:41 +00004725 if (!clang_isDeclaration(C.kind))
4726 return clang_getNullLocation();
4727
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004728 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004729 if (!D)
4730 return clang_getNullLocation();
4731
4732 SourceLocation Loc = D->getLocation();
4733 // FIXME: Multiple variables declared in a single declaration
4734 // currently lack the information needed to correctly determine their
4735 // ranges when accounting for the type-specifier. We use context
4736 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4737 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004738 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004739 if (!cxcursor::isFirstInDeclGroup(C))
4740 Loc = VD->getLocation();
4741 }
4742
4743 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004744 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004745 Loc = MD->getSelectorStartLoc();
4746
4747 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4748}
4749
4750} // end extern "C"
4751
4752CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4753 assert(TU);
4754
4755 // Guard against an invalid SourceLocation, or we may assert in one
4756 // of the following calls.
4757 if (SLoc.isInvalid())
4758 return clang_getNullCursor();
4759
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004760 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004761
4762 // Translate the given source location to make it point at the beginning of
4763 // the token under the cursor.
4764 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4765 CXXUnit->getASTContext().getLangOpts());
4766
4767 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4768 if (SLoc.isValid()) {
4769 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4770 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4771 /*VisitPreprocessorLast=*/true,
4772 /*VisitIncludedEntities=*/false,
4773 SourceLocation(SLoc));
4774 CursorVis.visitFileRegion();
4775 }
4776
4777 return Result;
4778}
4779
4780static SourceRange getRawCursorExtent(CXCursor C) {
4781 if (clang_isReference(C.kind)) {
4782 switch (C.kind) {
4783 case CXCursor_ObjCSuperClassRef:
4784 return getCursorObjCSuperClassRef(C).second;
4785
4786 case CXCursor_ObjCProtocolRef:
4787 return getCursorObjCProtocolRef(C).second;
4788
4789 case CXCursor_ObjCClassRef:
4790 return getCursorObjCClassRef(C).second;
4791
4792 case CXCursor_TypeRef:
4793 return getCursorTypeRef(C).second;
4794
4795 case CXCursor_TemplateRef:
4796 return getCursorTemplateRef(C).second;
4797
4798 case CXCursor_NamespaceRef:
4799 return getCursorNamespaceRef(C).second;
4800
4801 case CXCursor_MemberRef:
4802 return getCursorMemberRef(C).second;
4803
4804 case CXCursor_CXXBaseSpecifier:
4805 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4806
4807 case CXCursor_LabelRef:
4808 return getCursorLabelRef(C).second;
4809
4810 case CXCursor_OverloadedDeclRef:
4811 return getCursorOverloadedDeclRef(C).second;
4812
4813 case CXCursor_VariableRef:
4814 return getCursorVariableRef(C).second;
4815
4816 default:
4817 // FIXME: Need a way to enumerate all non-reference cases.
4818 llvm_unreachable("Missed a reference kind");
4819 }
4820 }
4821
4822 if (clang_isExpression(C.kind))
4823 return getCursorExpr(C)->getSourceRange();
4824
4825 if (clang_isStatement(C.kind))
4826 return getCursorStmt(C)->getSourceRange();
4827
4828 if (clang_isAttribute(C.kind))
4829 return getCursorAttr(C)->getRange();
4830
4831 if (C.kind == CXCursor_PreprocessingDirective)
4832 return cxcursor::getCursorPreprocessingDirective(C);
4833
4834 if (C.kind == CXCursor_MacroExpansion) {
4835 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004836 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004837 return TU->mapRangeFromPreamble(Range);
4838 }
4839
4840 if (C.kind == CXCursor_MacroDefinition) {
4841 ASTUnit *TU = getCursorASTUnit(C);
4842 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4843 return TU->mapRangeFromPreamble(Range);
4844 }
4845
4846 if (C.kind == CXCursor_InclusionDirective) {
4847 ASTUnit *TU = getCursorASTUnit(C);
4848 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4849 return TU->mapRangeFromPreamble(Range);
4850 }
4851
4852 if (C.kind == CXCursor_TranslationUnit) {
4853 ASTUnit *TU = getCursorASTUnit(C);
4854 FileID MainID = TU->getSourceManager().getMainFileID();
4855 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4856 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4857 return SourceRange(Start, End);
4858 }
4859
4860 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004861 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004862 if (!D)
4863 return SourceRange();
4864
4865 SourceRange R = D->getSourceRange();
4866 // FIXME: Multiple variables declared in a single declaration
4867 // currently lack the information needed to correctly determine their
4868 // ranges when accounting for the type-specifier. We use context
4869 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4870 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004871 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004872 if (!cxcursor::isFirstInDeclGroup(C))
4873 R.setBegin(VD->getLocation());
4874 }
4875 return R;
4876 }
4877 return SourceRange();
4878}
4879
4880/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4881/// the decl-specifier-seq for declarations.
4882static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4883 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004884 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004885 if (!D)
4886 return SourceRange();
4887
4888 SourceRange R = D->getSourceRange();
4889
4890 // Adjust the start of the location for declarations preceded by
4891 // declaration specifiers.
4892 SourceLocation StartLoc;
4893 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4894 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4895 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004896 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004897 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4898 StartLoc = TI->getTypeLoc().getLocStart();
4899 }
4900
4901 if (StartLoc.isValid() && R.getBegin().isValid() &&
4902 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4903 R.setBegin(StartLoc);
4904
4905 // FIXME: Multiple variables declared in a single declaration
4906 // currently lack the information needed to correctly determine their
4907 // ranges when accounting for the type-specifier. We use context
4908 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4909 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004910 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004911 if (!cxcursor::isFirstInDeclGroup(C))
4912 R.setBegin(VD->getLocation());
4913 }
4914
4915 return R;
4916 }
4917
4918 return getRawCursorExtent(C);
4919}
4920
4921extern "C" {
4922
4923CXSourceRange clang_getCursorExtent(CXCursor C) {
4924 SourceRange R = getRawCursorExtent(C);
4925 if (R.isInvalid())
4926 return clang_getNullRange();
4927
4928 return cxloc::translateSourceRange(getCursorContext(C), R);
4929}
4930
4931CXCursor clang_getCursorReferenced(CXCursor C) {
4932 if (clang_isInvalid(C.kind))
4933 return clang_getNullCursor();
4934
4935 CXTranslationUnit tu = getCursorTU(C);
4936 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004937 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004938 if (!D)
4939 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004940 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004941 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004942 if (const ObjCPropertyImplDecl *PropImpl =
4943 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004944 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4945 return MakeCXCursor(Property, tu);
4946
4947 return C;
4948 }
4949
4950 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004951 const Expr *E = getCursorExpr(C);
4952 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004953 if (D) {
4954 CXCursor declCursor = MakeCXCursor(D, tu);
4955 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4956 declCursor);
4957 return declCursor;
4958 }
4959
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004960 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004961 return MakeCursorOverloadedDeclRef(Ovl, tu);
4962
4963 return clang_getNullCursor();
4964 }
4965
4966 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004967 const Stmt *S = getCursorStmt(C);
4968 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004969 if (LabelDecl *label = Goto->getLabel())
4970 if (LabelStmt *labelS = label->getStmt())
4971 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4972
4973 return clang_getNullCursor();
4974 }
Richard Smith66a81862015-05-04 02:25:31 +00004975
Guy Benyei11169dd2012-12-18 14:30:41 +00004976 if (C.kind == CXCursor_MacroExpansion) {
Richard Smith66a81862015-05-04 02:25:31 +00004977 if (const MacroDefinitionRecord *Def =
4978 getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004979 return MakeMacroDefinitionCursor(Def, tu);
4980 }
4981
4982 if (!clang_isReference(C.kind))
4983 return clang_getNullCursor();
4984
4985 switch (C.kind) {
4986 case CXCursor_ObjCSuperClassRef:
4987 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4988
4989 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004990 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4991 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004992 return MakeCXCursor(Def, tu);
4993
4994 return MakeCXCursor(Prot, tu);
4995 }
4996
4997 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004998 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4999 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005000 return MakeCXCursor(Def, tu);
5001
5002 return MakeCXCursor(Class, tu);
5003 }
5004
5005 case CXCursor_TypeRef:
5006 return MakeCXCursor(getCursorTypeRef(C).first, tu );
5007
5008 case CXCursor_TemplateRef:
5009 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
5010
5011 case CXCursor_NamespaceRef:
5012 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
5013
5014 case CXCursor_MemberRef:
5015 return MakeCXCursor(getCursorMemberRef(C).first, tu );
5016
5017 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005018 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005019 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
5020 tu ));
5021 }
5022
5023 case CXCursor_LabelRef:
5024 // FIXME: We end up faking the "parent" declaration here because we
5025 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005026 return MakeCXCursor(getCursorLabelRef(C).first,
5027 cxtu::getASTUnit(tu)->getASTContext()
5028 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00005029 tu);
5030
5031 case CXCursor_OverloadedDeclRef:
5032 return C;
5033
5034 case CXCursor_VariableRef:
5035 return MakeCXCursor(getCursorVariableRef(C).first, tu);
5036
5037 default:
5038 // We would prefer to enumerate all non-reference cursor kinds here.
5039 llvm_unreachable("Unhandled reference cursor kind");
5040 }
5041}
5042
5043CXCursor clang_getCursorDefinition(CXCursor C) {
5044 if (clang_isInvalid(C.kind))
5045 return clang_getNullCursor();
5046
5047 CXTranslationUnit TU = getCursorTU(C);
5048
5049 bool WasReference = false;
5050 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
5051 C = clang_getCursorReferenced(C);
5052 WasReference = true;
5053 }
5054
5055 if (C.kind == CXCursor_MacroExpansion)
5056 return clang_getCursorReferenced(C);
5057
5058 if (!clang_isDeclaration(C.kind))
5059 return clang_getNullCursor();
5060
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005061 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005062 if (!D)
5063 return clang_getNullCursor();
5064
5065 switch (D->getKind()) {
5066 // Declaration kinds that don't really separate the notions of
5067 // declaration and definition.
5068 case Decl::Namespace:
5069 case Decl::Typedef:
5070 case Decl::TypeAlias:
5071 case Decl::TypeAliasTemplate:
5072 case Decl::TemplateTypeParm:
5073 case Decl::EnumConstant:
5074 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00005075 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005076 case Decl::IndirectField:
5077 case Decl::ObjCIvar:
5078 case Decl::ObjCAtDefsField:
5079 case Decl::ImplicitParam:
5080 case Decl::ParmVar:
5081 case Decl::NonTypeTemplateParm:
5082 case Decl::TemplateTemplateParm:
5083 case Decl::ObjCCategoryImpl:
5084 case Decl::ObjCImplementation:
5085 case Decl::AccessSpec:
5086 case Decl::LinkageSpec:
5087 case Decl::ObjCPropertyImpl:
5088 case Decl::FileScopeAsm:
5089 case Decl::StaticAssert:
5090 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00005091 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00005092 case Decl::Label: // FIXME: Is this right??
5093 case Decl::ClassScopeFunctionSpecialization:
5094 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00005095 case Decl::OMPThreadPrivate:
Douglas Gregor85f3f952015-07-07 03:57:15 +00005096 case Decl::ObjCTypeParam:
Guy Benyei11169dd2012-12-18 14:30:41 +00005097 return C;
5098
5099 // Declaration kinds that don't make any sense here, but are
5100 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00005101 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005102 case Decl::TranslationUnit:
Richard Smithf19e1272015-03-07 00:04:49 +00005103 case Decl::ExternCContext:
Guy Benyei11169dd2012-12-18 14:30:41 +00005104 break;
5105
5106 // Declaration kinds for which the definition is not resolvable.
5107 case Decl::UnresolvedUsingTypename:
5108 case Decl::UnresolvedUsingValue:
5109 break;
5110
5111 case Decl::UsingDirective:
5112 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
5113 TU);
5114
5115 case Decl::NamespaceAlias:
5116 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
5117
5118 case Decl::Enum:
5119 case Decl::Record:
5120 case Decl::CXXRecord:
5121 case Decl::ClassTemplateSpecialization:
5122 case Decl::ClassTemplatePartialSpecialization:
5123 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
5124 return MakeCXCursor(Def, TU);
5125 return clang_getNullCursor();
5126
5127 case Decl::Function:
5128 case Decl::CXXMethod:
5129 case Decl::CXXConstructor:
5130 case Decl::CXXDestructor:
5131 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00005132 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005133 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00005134 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005135 return clang_getNullCursor();
5136 }
5137
Larisse Voufo39a1e502013-08-06 01:03:05 +00005138 case Decl::Var:
5139 case Decl::VarTemplateSpecialization:
5140 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00005141 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005142 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005143 return MakeCXCursor(Def, TU);
5144 return clang_getNullCursor();
5145 }
5146
5147 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00005148 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005149 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
5150 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
5151 return clang_getNullCursor();
5152 }
5153
5154 case Decl::ClassTemplate: {
5155 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
5156 ->getDefinition())
5157 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
5158 TU);
5159 return clang_getNullCursor();
5160 }
5161
Larisse Voufo39a1e502013-08-06 01:03:05 +00005162 case Decl::VarTemplate: {
5163 if (VarDecl *Def =
5164 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
5165 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
5166 return clang_getNullCursor();
5167 }
5168
Guy Benyei11169dd2012-12-18 14:30:41 +00005169 case Decl::Using:
5170 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
5171 D->getLocation(), TU);
5172
5173 case Decl::UsingShadow:
5174 return clang_getCursorDefinition(
5175 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
5176 TU));
5177
5178 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005179 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005180 if (Method->isThisDeclarationADefinition())
5181 return C;
5182
5183 // Dig out the method definition in the associated
5184 // @implementation, if we have it.
5185 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005186 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005187 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
5188 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
5189 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
5190 Method->isInstanceMethod()))
5191 if (Def->isThisDeclarationADefinition())
5192 return MakeCXCursor(Def, TU);
5193
5194 return clang_getNullCursor();
5195 }
5196
5197 case Decl::ObjCCategory:
5198 if (ObjCCategoryImplDecl *Impl
5199 = cast<ObjCCategoryDecl>(D)->getImplementation())
5200 return MakeCXCursor(Impl, TU);
5201 return clang_getNullCursor();
5202
5203 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005204 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005205 return MakeCXCursor(Def, TU);
5206 return clang_getNullCursor();
5207
5208 case Decl::ObjCInterface: {
5209 // There are two notions of a "definition" for an Objective-C
5210 // class: the interface and its implementation. When we resolved a
5211 // reference to an Objective-C class, produce the @interface as
5212 // the definition; when we were provided with the interface,
5213 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005214 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005215 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005216 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005217 return MakeCXCursor(Def, TU);
5218 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
5219 return MakeCXCursor(Impl, TU);
5220 return clang_getNullCursor();
5221 }
5222
5223 case Decl::ObjCProperty:
5224 // FIXME: We don't really know where to find the
5225 // ObjCPropertyImplDecls that implement this property.
5226 return clang_getNullCursor();
5227
5228 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005229 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005230 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005231 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005232 return MakeCXCursor(Def, TU);
5233
5234 return clang_getNullCursor();
5235
5236 case Decl::Friend:
5237 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
5238 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5239 return clang_getNullCursor();
5240
5241 case Decl::FriendTemplate:
5242 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
5243 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5244 return clang_getNullCursor();
5245 }
5246
5247 return clang_getNullCursor();
5248}
5249
5250unsigned clang_isCursorDefinition(CXCursor C) {
5251 if (!clang_isDeclaration(C.kind))
5252 return 0;
5253
5254 return clang_getCursorDefinition(C) == C;
5255}
5256
5257CXCursor clang_getCanonicalCursor(CXCursor C) {
5258 if (!clang_isDeclaration(C.kind))
5259 return C;
5260
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005261 if (const Decl *D = getCursorDecl(C)) {
5262 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005263 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5264 return MakeCXCursor(CatD, getCursorTU(C));
5265
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005266 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5267 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00005268 return MakeCXCursor(IFD, getCursorTU(C));
5269
5270 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5271 }
5272
5273 return C;
5274}
5275
5276int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5277 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5278}
5279
5280unsigned clang_getNumOverloadedDecls(CXCursor C) {
5281 if (C.kind != CXCursor_OverloadedDeclRef)
5282 return 0;
5283
5284 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005285 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005286 return E->getNumDecls();
5287
5288 if (OverloadedTemplateStorage *S
5289 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5290 return S->size();
5291
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005292 const Decl *D = Storage.get<const Decl *>();
5293 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005294 return Using->shadow_size();
5295
5296 return 0;
5297}
5298
5299CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5300 if (cursor.kind != CXCursor_OverloadedDeclRef)
5301 return clang_getNullCursor();
5302
5303 if (index >= clang_getNumOverloadedDecls(cursor))
5304 return clang_getNullCursor();
5305
5306 CXTranslationUnit TU = getCursorTU(cursor);
5307 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005308 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005309 return MakeCXCursor(E->decls_begin()[index], TU);
5310
5311 if (OverloadedTemplateStorage *S
5312 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5313 return MakeCXCursor(S->begin()[index], TU);
5314
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005315 const Decl *D = Storage.get<const Decl *>();
5316 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005317 // FIXME: This is, unfortunately, linear time.
5318 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5319 std::advance(Pos, index);
5320 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5321 }
5322
5323 return clang_getNullCursor();
5324}
5325
5326void clang_getDefinitionSpellingAndExtent(CXCursor C,
5327 const char **startBuf,
5328 const char **endBuf,
5329 unsigned *startLine,
5330 unsigned *startColumn,
5331 unsigned *endLine,
5332 unsigned *endColumn) {
5333 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005334 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005335 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5336
5337 SourceManager &SM = FD->getASTContext().getSourceManager();
5338 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5339 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5340 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5341 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5342 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5343 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5344}
5345
5346
5347CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5348 unsigned PieceIndex) {
5349 RefNamePieces Pieces;
5350
5351 switch (C.kind) {
5352 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005353 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005354 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5355 E->getQualifierLoc().getSourceRange());
5356 break;
5357
5358 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005359 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005360 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
5361 E->getQualifierLoc().getSourceRange(),
5362 E->getOptionalExplicitTemplateArgs());
5363 break;
5364
5365 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005366 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005367 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005368 const Expr *Callee = OCE->getCallee();
5369 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005370 Callee = ICE->getSubExpr();
5371
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005372 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005373 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5374 DRE->getQualifierLoc().getSourceRange());
5375 }
5376 break;
5377
5378 default:
5379 break;
5380 }
5381
5382 if (Pieces.empty()) {
5383 if (PieceIndex == 0)
5384 return clang_getCursorExtent(C);
5385 } else if (PieceIndex < Pieces.size()) {
5386 SourceRange R = Pieces[PieceIndex];
5387 if (R.isValid())
5388 return cxloc::translateSourceRange(getCursorContext(C), R);
5389 }
5390
5391 return clang_getNullRange();
5392}
5393
5394void clang_enableStackTraces(void) {
5395 llvm::sys::PrintStackTraceOnErrorSignal();
5396}
5397
5398void clang_executeOnThread(void (*fn)(void*), void *user_data,
5399 unsigned stack_size) {
5400 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5401}
5402
5403} // end: extern "C"
5404
5405//===----------------------------------------------------------------------===//
5406// Token-based Operations.
5407//===----------------------------------------------------------------------===//
5408
5409/* CXToken layout:
5410 * int_data[0]: a CXTokenKind
5411 * int_data[1]: starting token location
5412 * int_data[2]: token length
5413 * int_data[3]: reserved
5414 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5415 * otherwise unused.
5416 */
5417extern "C" {
5418
5419CXTokenKind clang_getTokenKind(CXToken CXTok) {
5420 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5421}
5422
5423CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5424 switch (clang_getTokenKind(CXTok)) {
5425 case CXToken_Identifier:
5426 case CXToken_Keyword:
5427 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005428 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005429 ->getNameStart());
5430
5431 case CXToken_Literal: {
5432 // We have stashed the starting pointer in the ptr_data field. Use it.
5433 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005434 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005435 }
5436
5437 case CXToken_Punctuation:
5438 case CXToken_Comment:
5439 break;
5440 }
5441
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005442 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005443 LOG_BAD_TU(TU);
5444 return cxstring::createEmpty();
5445 }
5446
Guy Benyei11169dd2012-12-18 14:30:41 +00005447 // We have to find the starting buffer pointer the hard way, by
5448 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005449 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005450 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005451 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005452
5453 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5454 std::pair<FileID, unsigned> LocInfo
5455 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5456 bool Invalid = false;
5457 StringRef Buffer
5458 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5459 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005460 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005461
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005462 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005463}
5464
5465CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005466 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005467 LOG_BAD_TU(TU);
5468 return clang_getNullLocation();
5469 }
5470
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005471 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005472 if (!CXXUnit)
5473 return clang_getNullLocation();
5474
5475 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5476 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5477}
5478
5479CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005480 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005481 LOG_BAD_TU(TU);
5482 return clang_getNullRange();
5483 }
5484
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005485 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005486 if (!CXXUnit)
5487 return clang_getNullRange();
5488
5489 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5490 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5491}
5492
5493static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5494 SmallVectorImpl<CXToken> &CXTokens) {
5495 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5496 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005497 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005498 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005499 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005500
5501 // Cannot tokenize across files.
5502 if (BeginLocInfo.first != EndLocInfo.first)
5503 return;
5504
5505 // Create a lexer
5506 bool Invalid = false;
5507 StringRef Buffer
5508 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5509 if (Invalid)
5510 return;
5511
5512 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5513 CXXUnit->getASTContext().getLangOpts(),
5514 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5515 Lex.SetCommentRetentionState(true);
5516
5517 // Lex tokens until we hit the end of the range.
5518 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5519 Token Tok;
5520 bool previousWasAt = false;
5521 do {
5522 // Lex the next token
5523 Lex.LexFromRawLexer(Tok);
5524 if (Tok.is(tok::eof))
5525 break;
5526
5527 // Initialize the CXToken.
5528 CXToken CXTok;
5529
5530 // - Common fields
5531 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5532 CXTok.int_data[2] = Tok.getLength();
5533 CXTok.int_data[3] = 0;
5534
5535 // - Kind-specific fields
5536 if (Tok.isLiteral()) {
5537 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005538 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005539 } else if (Tok.is(tok::raw_identifier)) {
5540 // Lookup the identifier to determine whether we have a keyword.
5541 IdentifierInfo *II
5542 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5543
5544 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5545 CXTok.int_data[0] = CXToken_Keyword;
5546 }
5547 else {
5548 CXTok.int_data[0] = Tok.is(tok::identifier)
5549 ? CXToken_Identifier
5550 : CXToken_Keyword;
5551 }
5552 CXTok.ptr_data = II;
5553 } else if (Tok.is(tok::comment)) {
5554 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005555 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005556 } else {
5557 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005558 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005559 }
5560 CXTokens.push_back(CXTok);
5561 previousWasAt = Tok.is(tok::at);
5562 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5563}
5564
5565void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5566 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005567 LOG_FUNC_SECTION {
5568 *Log << TU << ' ' << Range;
5569 }
5570
Guy Benyei11169dd2012-12-18 14:30:41 +00005571 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005572 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005573 if (NumTokens)
5574 *NumTokens = 0;
5575
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005576 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005577 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005578 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005579 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005580
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005581 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005582 if (!CXXUnit || !Tokens || !NumTokens)
5583 return;
5584
5585 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5586
5587 SourceRange R = cxloc::translateCXSourceRange(Range);
5588 if (R.isInvalid())
5589 return;
5590
5591 SmallVector<CXToken, 32> CXTokens;
5592 getTokens(CXXUnit, R, CXTokens);
5593
5594 if (CXTokens.empty())
5595 return;
5596
5597 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5598 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5599 *NumTokens = CXTokens.size();
5600}
5601
5602void clang_disposeTokens(CXTranslationUnit TU,
5603 CXToken *Tokens, unsigned NumTokens) {
5604 free(Tokens);
5605}
5606
5607} // end: extern "C"
5608
5609//===----------------------------------------------------------------------===//
5610// Token annotation APIs.
5611//===----------------------------------------------------------------------===//
5612
Guy Benyei11169dd2012-12-18 14:30:41 +00005613static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5614 CXCursor parent,
5615 CXClientData client_data);
5616static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5617 CXClientData client_data);
5618
5619namespace {
5620class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005621 CXToken *Tokens;
5622 CXCursor *Cursors;
5623 unsigned NumTokens;
5624 unsigned TokIdx;
5625 unsigned PreprocessingTokIdx;
5626 CursorVisitor AnnotateVis;
5627 SourceManager &SrcMgr;
5628 bool HasContextSensitiveKeywords;
5629
5630 struct PostChildrenInfo {
5631 CXCursor Cursor;
5632 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005633 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005634 unsigned BeforeChildrenTokenIdx;
5635 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005636 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005637
5638 CXToken &getTok(unsigned Idx) {
5639 assert(Idx < NumTokens);
5640 return Tokens[Idx];
5641 }
5642 const CXToken &getTok(unsigned Idx) const {
5643 assert(Idx < NumTokens);
5644 return Tokens[Idx];
5645 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005646 bool MoreTokens() const { return TokIdx < NumTokens; }
5647 unsigned NextToken() const { return TokIdx; }
5648 void AdvanceToken() { ++TokIdx; }
5649 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005650 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005651 }
5652 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005653 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005654 }
5655 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005656 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005657 }
5658
5659 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005660 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005661 SourceRange);
5662
5663public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005664 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005665 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005666 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005667 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005668 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005669 AnnotateTokensVisitor, this,
5670 /*VisitPreprocessorLast=*/true,
5671 /*VisitIncludedEntities=*/false,
5672 RegionOfInterest,
5673 /*VisitDeclsOnly=*/false,
5674 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005675 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005676 HasContextSensitiveKeywords(false) { }
5677
5678 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5679 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5680 bool postVisitChildren(CXCursor cursor);
5681 void AnnotateTokens();
5682
5683 /// \brief Determine whether the annotator saw any cursors that have
5684 /// context-sensitive keywords.
5685 bool hasContextSensitiveKeywords() const {
5686 return HasContextSensitiveKeywords;
5687 }
5688
5689 ~AnnotateTokensWorker() {
5690 assert(PostChildrenInfos.empty());
5691 }
5692};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00005693}
Guy Benyei11169dd2012-12-18 14:30:41 +00005694
5695void AnnotateTokensWorker::AnnotateTokens() {
5696 // Walk the AST within the region of interest, annotating tokens
5697 // along the way.
5698 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005699}
Guy Benyei11169dd2012-12-18 14:30:41 +00005700
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005701static inline void updateCursorAnnotation(CXCursor &Cursor,
5702 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005703 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005704 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005705 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005706}
5707
5708/// \brief It annotates and advances tokens with a cursor until the comparison
5709//// between the cursor location and the source range is the same as
5710/// \arg compResult.
5711///
5712/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5713/// Pass RangeOverlap to annotate tokens inside a range.
5714void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5715 RangeComparisonResult compResult,
5716 SourceRange range) {
5717 while (MoreTokens()) {
5718 const unsigned I = NextToken();
5719 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005720 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5721 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005722
5723 SourceLocation TokLoc = GetTokenLoc(I);
5724 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005725 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005726 AdvanceToken();
5727 continue;
5728 }
5729 break;
5730 }
5731}
5732
5733/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005734/// \returns true if it advanced beyond all macro tokens, false otherwise.
5735bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005736 CXCursor updateC,
5737 RangeComparisonResult compResult,
5738 SourceRange range) {
5739 assert(MoreTokens());
5740 assert(isFunctionMacroToken(NextToken()) &&
5741 "Should be called only for macro arg tokens");
5742
5743 // This works differently than annotateAndAdvanceTokens; because expanded
5744 // macro arguments can have arbitrary translation-unit source order, we do not
5745 // advance the token index one by one until a token fails the range test.
5746 // We only advance once past all of the macro arg tokens if all of them
5747 // pass the range test. If one of them fails we keep the token index pointing
5748 // at the start of the macro arg tokens so that the failing token will be
5749 // annotated by a subsequent annotation try.
5750
5751 bool atLeastOneCompFail = false;
5752
5753 unsigned I = NextToken();
5754 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5755 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5756 if (TokLoc.isFileID())
5757 continue; // not macro arg token, it's parens or comma.
5758 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5759 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5760 Cursors[I] = updateC;
5761 } else
5762 atLeastOneCompFail = true;
5763 }
5764
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005765 if (atLeastOneCompFail)
5766 return false;
5767
5768 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5769 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005770}
5771
5772enum CXChildVisitResult
5773AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005774 SourceRange cursorRange = getRawCursorExtent(cursor);
5775 if (cursorRange.isInvalid())
5776 return CXChildVisit_Recurse;
5777
5778 if (!HasContextSensitiveKeywords) {
5779 // Objective-C properties can have context-sensitive keywords.
5780 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005781 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005782 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5783 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5784 }
5785 // Objective-C methods can have context-sensitive keywords.
5786 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5787 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005788 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005789 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5790 if (Method->getObjCDeclQualifier())
5791 HasContextSensitiveKeywords = true;
5792 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005793 for (const auto *P : Method->params()) {
5794 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005795 HasContextSensitiveKeywords = true;
5796 break;
5797 }
5798 }
5799 }
5800 }
5801 }
5802 // C++ methods can have context-sensitive keywords.
5803 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005804 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005805 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5806 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5807 HasContextSensitiveKeywords = true;
5808 }
5809 }
5810 // C++ classes can have context-sensitive keywords.
5811 else if (cursor.kind == CXCursor_StructDecl ||
5812 cursor.kind == CXCursor_ClassDecl ||
5813 cursor.kind == CXCursor_ClassTemplate ||
5814 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005815 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005816 if (D->hasAttr<FinalAttr>())
5817 HasContextSensitiveKeywords = true;
5818 }
5819 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005820
5821 // Don't override a property annotation with its getter/setter method.
5822 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5823 parent.kind == CXCursor_ObjCPropertyDecl)
5824 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005825
5826 if (clang_isPreprocessing(cursor.kind)) {
5827 // Items in the preprocessing record are kept separate from items in
5828 // declarations, so we keep a separate token index.
5829 unsigned SavedTokIdx = TokIdx;
5830 TokIdx = PreprocessingTokIdx;
5831
5832 // Skip tokens up until we catch up to the beginning of the preprocessing
5833 // entry.
5834 while (MoreTokens()) {
5835 const unsigned I = NextToken();
5836 SourceLocation TokLoc = GetTokenLoc(I);
5837 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5838 case RangeBefore:
5839 AdvanceToken();
5840 continue;
5841 case RangeAfter:
5842 case RangeOverlap:
5843 break;
5844 }
5845 break;
5846 }
5847
5848 // Look at all of the tokens within this range.
5849 while (MoreTokens()) {
5850 const unsigned I = NextToken();
5851 SourceLocation TokLoc = GetTokenLoc(I);
5852 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5853 case RangeBefore:
5854 llvm_unreachable("Infeasible");
5855 case RangeAfter:
5856 break;
5857 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005858 // For macro expansions, just note where the beginning of the macro
5859 // expansion occurs.
5860 if (cursor.kind == CXCursor_MacroExpansion) {
5861 if (TokLoc == cursorRange.getBegin())
5862 Cursors[I] = cursor;
5863 AdvanceToken();
5864 break;
5865 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005866 // We may have already annotated macro names inside macro definitions.
5867 if (Cursors[I].kind != CXCursor_MacroExpansion)
5868 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005869 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005870 continue;
5871 }
5872 break;
5873 }
5874
5875 // Save the preprocessing token index; restore the non-preprocessing
5876 // token index.
5877 PreprocessingTokIdx = TokIdx;
5878 TokIdx = SavedTokIdx;
5879 return CXChildVisit_Recurse;
5880 }
5881
5882 if (cursorRange.isInvalid())
5883 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005884
5885 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005886 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005887 const enum CXCursorKind K = clang_getCursorKind(parent);
5888 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005889 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5890 // Attributes are annotated out-of-order, skip tokens until we reach it.
5891 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005892 ? clang_getNullCursor() : parent;
5893
5894 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5895
5896 // Avoid having the cursor of an expression "overwrite" the annotation of the
5897 // variable declaration that it belongs to.
5898 // This can happen for C++ constructor expressions whose range generally
5899 // include the variable declaration, e.g.:
5900 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005901 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005902 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005903 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005904 const unsigned I = NextToken();
5905 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5906 E->getLocStart() == D->getLocation() &&
5907 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005908 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005909 AdvanceToken();
5910 }
5911 }
5912 }
5913
5914 // Before recursing into the children keep some state that we are going
5915 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5916 // extra work after the child nodes are visited.
5917 // Note that we don't call VisitChildren here to avoid traversing statements
5918 // code-recursively which can blow the stack.
5919
5920 PostChildrenInfo Info;
5921 Info.Cursor = cursor;
5922 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005923 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005924 Info.BeforeChildrenTokenIdx = NextToken();
5925 PostChildrenInfos.push_back(Info);
5926
5927 return CXChildVisit_Recurse;
5928}
5929
5930bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5931 if (PostChildrenInfos.empty())
5932 return false;
5933 const PostChildrenInfo &Info = PostChildrenInfos.back();
5934 if (!clang_equalCursors(Info.Cursor, cursor))
5935 return false;
5936
5937 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5938 const unsigned AfterChildren = NextToken();
5939 SourceRange cursorRange = Info.CursorRange;
5940
5941 // Scan the tokens that are at the end of the cursor, but are not captured
5942 // but the child cursors.
5943 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5944
5945 // Scan the tokens that are at the beginning of the cursor, but are not
5946 // capture by the child cursors.
5947 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5948 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5949 break;
5950
5951 Cursors[I] = cursor;
5952 }
5953
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005954 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5955 // encountered the attribute cursor.
5956 if (clang_isAttribute(cursor.kind))
5957 TokIdx = Info.BeforeReachingCursorIdx;
5958
Guy Benyei11169dd2012-12-18 14:30:41 +00005959 PostChildrenInfos.pop_back();
5960 return false;
5961}
5962
5963static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5964 CXCursor parent,
5965 CXClientData client_data) {
5966 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5967}
5968
5969static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5970 CXClientData client_data) {
5971 return static_cast<AnnotateTokensWorker*>(client_data)->
5972 postVisitChildren(cursor);
5973}
5974
5975namespace {
5976
5977/// \brief Uses the macro expansions in the preprocessing record to find
5978/// and mark tokens that are macro arguments. This info is used by the
5979/// AnnotateTokensWorker.
5980class MarkMacroArgTokensVisitor {
5981 SourceManager &SM;
5982 CXToken *Tokens;
5983 unsigned NumTokens;
5984 unsigned CurIdx;
5985
5986public:
5987 MarkMacroArgTokensVisitor(SourceManager &SM,
5988 CXToken *tokens, unsigned numTokens)
5989 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5990
5991 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5992 if (cursor.kind != CXCursor_MacroExpansion)
5993 return CXChildVisit_Continue;
5994
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005995 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005996 if (macroRange.getBegin() == macroRange.getEnd())
5997 return CXChildVisit_Continue; // it's not a function macro.
5998
5999 for (; CurIdx < NumTokens; ++CurIdx) {
6000 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
6001 macroRange.getBegin()))
6002 break;
6003 }
6004
6005 if (CurIdx == NumTokens)
6006 return CXChildVisit_Break;
6007
6008 for (; CurIdx < NumTokens; ++CurIdx) {
6009 SourceLocation tokLoc = getTokenLoc(CurIdx);
6010 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
6011 break;
6012
6013 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
6014 }
6015
6016 if (CurIdx == NumTokens)
6017 return CXChildVisit_Break;
6018
6019 return CXChildVisit_Continue;
6020 }
6021
6022private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006023 CXToken &getTok(unsigned Idx) {
6024 assert(Idx < NumTokens);
6025 return Tokens[Idx];
6026 }
6027 const CXToken &getTok(unsigned Idx) const {
6028 assert(Idx < NumTokens);
6029 return Tokens[Idx];
6030 }
6031
Guy Benyei11169dd2012-12-18 14:30:41 +00006032 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006033 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006034 }
6035
6036 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
6037 // The third field is reserved and currently not used. Use it here
6038 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006039 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00006040 }
6041};
6042
6043} // end anonymous namespace
6044
6045static CXChildVisitResult
6046MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
6047 CXClientData client_data) {
6048 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
6049 parent);
6050}
6051
6052namespace {
6053 struct clang_annotateTokens_Data {
6054 CXTranslationUnit TU;
6055 ASTUnit *CXXUnit;
6056 CXToken *Tokens;
6057 unsigned NumTokens;
6058 CXCursor *Cursors;
6059 };
6060}
6061
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006062/// \brief Used by \c annotatePreprocessorTokens.
6063/// \returns true if lexing was finished, false otherwise.
6064static bool lexNext(Lexer &Lex, Token &Tok,
6065 unsigned &NextIdx, unsigned NumTokens) {
6066 if (NextIdx >= NumTokens)
6067 return true;
6068
6069 ++NextIdx;
6070 Lex.LexFromRawLexer(Tok);
6071 if (Tok.is(tok::eof))
6072 return true;
6073
6074 return false;
6075}
6076
Guy Benyei11169dd2012-12-18 14:30:41 +00006077static void annotatePreprocessorTokens(CXTranslationUnit TU,
6078 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006079 CXCursor *Cursors,
6080 CXToken *Tokens,
6081 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006082 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006083
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006084 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00006085 SourceManager &SourceMgr = CXXUnit->getSourceManager();
6086 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006087 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00006088 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006089 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00006090
6091 if (BeginLocInfo.first != EndLocInfo.first)
6092 return;
6093
6094 StringRef Buffer;
6095 bool Invalid = false;
6096 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
6097 if (Buffer.empty() || Invalid)
6098 return;
6099
6100 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
6101 CXXUnit->getASTContext().getLangOpts(),
6102 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
6103 Buffer.end());
6104 Lex.SetCommentRetentionState(true);
6105
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006106 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006107 // Lex tokens in raw mode until we hit the end of the range, to avoid
6108 // entering #includes or expanding macros.
6109 while (true) {
6110 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006111 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6112 break;
6113 unsigned TokIdx = NextIdx-1;
6114 assert(Tok.getLocation() ==
6115 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006116
6117 reprocess:
6118 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006119 // We have found a preprocessing directive. Annotate the tokens
6120 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00006121 //
6122 // FIXME: Some simple tests here could identify macro definitions and
6123 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006124
6125 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006126 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6127 break;
6128
Craig Topper69186e72014-06-08 08:38:04 +00006129 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00006130 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006131 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6132 break;
6133
6134 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00006135 IdentifierInfo &II =
6136 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006137 SourceLocation MappedTokLoc =
6138 CXXUnit->mapLocationToPreamble(Tok.getLocation());
6139 MI = getMacroInfo(II, MappedTokLoc, TU);
6140 }
6141 }
6142
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006143 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00006144 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006145 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
6146 finished = true;
6147 break;
6148 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006149 // If we are in a macro definition, check if the token was ever a
6150 // macro name and annotate it if that's the case.
6151 if (MI) {
6152 SourceLocation SaveLoc = Tok.getLocation();
6153 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
Richard Smith66a81862015-05-04 02:25:31 +00006154 MacroDefinitionRecord *MacroDef =
6155 checkForMacroInMacroDefinition(MI, Tok, TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006156 Tok.setLocation(SaveLoc);
6157 if (MacroDef)
Richard Smith66a81862015-05-04 02:25:31 +00006158 Cursors[NextIdx - 1] =
6159 MakeMacroExpansionCursor(MacroDef, Tok.getLocation(), TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006160 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006161 } while (!Tok.isAtStartOfLine());
6162
6163 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
6164 assert(TokIdx <= LastIdx);
6165 SourceLocation EndLoc =
6166 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
6167 CXCursor Cursor =
6168 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
6169
6170 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006171 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006172
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006173 if (finished)
6174 break;
6175 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00006176 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006177 }
6178}
6179
6180// This gets run a separate thread to avoid stack blowout.
6181static void clang_annotateTokensImpl(void *UserData) {
6182 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
6183 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
6184 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
6185 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
6186 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
6187
Dmitri Gribenko183436e2013-01-26 21:49:50 +00006188 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006189 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
6190 setThreadBackgroundPriority();
6191
6192 // Determine the region of interest, which contains all of the tokens.
6193 SourceRange RegionOfInterest;
6194 RegionOfInterest.setBegin(
6195 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
6196 RegionOfInterest.setEnd(
6197 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
6198 Tokens[NumTokens-1])));
6199
Guy Benyei11169dd2012-12-18 14:30:41 +00006200 // Relex the tokens within the source range to look for preprocessing
6201 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006202 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006203
6204 // If begin location points inside a macro argument, set it to the expansion
6205 // location so we can have the full context when annotating semantically.
6206 {
6207 SourceManager &SM = CXXUnit->getSourceManager();
6208 SourceLocation Loc =
6209 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
6210 if (Loc.isMacroID())
6211 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
6212 }
6213
Guy Benyei11169dd2012-12-18 14:30:41 +00006214 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
6215 // Search and mark tokens that are macro argument expansions.
6216 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
6217 Tokens, NumTokens);
6218 CursorVisitor MacroArgMarker(TU,
6219 MarkMacroArgTokensVisitorDelegate, &Visitor,
6220 /*VisitPreprocessorLast=*/true,
6221 /*VisitIncludedEntities=*/false,
6222 RegionOfInterest);
6223 MacroArgMarker.visitPreprocessedEntitiesInRegion();
6224 }
6225
6226 // Annotate all of the source locations in the region of interest that map to
6227 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006228 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00006229
6230 // FIXME: We use a ridiculous stack size here because the data-recursion
6231 // algorithm uses a large stack frame than the non-data recursive version,
6232 // and AnnotationTokensWorker currently transforms the data-recursion
6233 // algorithm back into a traditional recursion by explicitly calling
6234 // VisitChildren(). We will need to remove this explicit recursive call.
6235 W.AnnotateTokens();
6236
6237 // If we ran into any entities that involve context-sensitive keywords,
6238 // take another pass through the tokens to mark them as such.
6239 if (W.hasContextSensitiveKeywords()) {
6240 for (unsigned I = 0; I != NumTokens; ++I) {
6241 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
6242 continue;
6243
6244 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
6245 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006246 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006247 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
6248 if (Property->getPropertyAttributesAsWritten() != 0 &&
6249 llvm::StringSwitch<bool>(II->getName())
6250 .Case("readonly", true)
6251 .Case("assign", true)
6252 .Case("unsafe_unretained", true)
6253 .Case("readwrite", true)
6254 .Case("retain", true)
6255 .Case("copy", true)
6256 .Case("nonatomic", true)
6257 .Case("atomic", true)
6258 .Case("getter", true)
6259 .Case("setter", true)
6260 .Case("strong", true)
6261 .Case("weak", true)
6262 .Default(false))
6263 Tokens[I].int_data[0] = CXToken_Keyword;
6264 }
6265 continue;
6266 }
6267
6268 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6269 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6270 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6271 if (llvm::StringSwitch<bool>(II->getName())
6272 .Case("in", true)
6273 .Case("out", true)
6274 .Case("inout", true)
6275 .Case("oneway", true)
6276 .Case("bycopy", true)
6277 .Case("byref", true)
6278 .Default(false))
6279 Tokens[I].int_data[0] = CXToken_Keyword;
6280 continue;
6281 }
6282
6283 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6284 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6285 Tokens[I].int_data[0] = CXToken_Keyword;
6286 continue;
6287 }
6288 }
6289 }
6290}
6291
6292extern "C" {
6293
6294void clang_annotateTokens(CXTranslationUnit TU,
6295 CXToken *Tokens, unsigned NumTokens,
6296 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006297 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006298 LOG_BAD_TU(TU);
6299 return;
6300 }
6301 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006302 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006303 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006304 }
6305
6306 LOG_FUNC_SECTION {
6307 *Log << TU << ' ';
6308 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6309 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6310 *Log << clang_getRange(bloc, eloc);
6311 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006312
6313 // Any token we don't specifically annotate will have a NULL cursor.
6314 CXCursor C = clang_getNullCursor();
6315 for (unsigned I = 0; I != NumTokens; ++I)
6316 Cursors[I] = C;
6317
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006318 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006319 if (!CXXUnit)
6320 return;
6321
6322 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
6323
6324 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
6325 llvm::CrashRecoveryContext CRC;
6326 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
6327 GetSafetyThreadStackSize() * 2)) {
6328 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6329 }
6330}
6331
6332} // end: extern "C"
6333
6334//===----------------------------------------------------------------------===//
6335// Operations for querying linkage of a cursor.
6336//===----------------------------------------------------------------------===//
6337
6338extern "C" {
6339CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6340 if (!clang_isDeclaration(cursor.kind))
6341 return CXLinkage_Invalid;
6342
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006343 const Decl *D = cxcursor::getCursorDecl(cursor);
6344 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006345 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006346 case NoLinkage:
6347 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006348 case InternalLinkage: return CXLinkage_Internal;
6349 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6350 case ExternalLinkage: return CXLinkage_External;
6351 };
6352
6353 return CXLinkage_Invalid;
6354}
6355} // end: extern "C"
6356
6357//===----------------------------------------------------------------------===//
6358// Operations for querying language of a cursor.
6359//===----------------------------------------------------------------------===//
6360
6361static CXLanguageKind getDeclLanguage(const Decl *D) {
6362 if (!D)
6363 return CXLanguage_C;
6364
6365 switch (D->getKind()) {
6366 default:
6367 break;
6368 case Decl::ImplicitParam:
6369 case Decl::ObjCAtDefsField:
6370 case Decl::ObjCCategory:
6371 case Decl::ObjCCategoryImpl:
6372 case Decl::ObjCCompatibleAlias:
6373 case Decl::ObjCImplementation:
6374 case Decl::ObjCInterface:
6375 case Decl::ObjCIvar:
6376 case Decl::ObjCMethod:
6377 case Decl::ObjCProperty:
6378 case Decl::ObjCPropertyImpl:
6379 case Decl::ObjCProtocol:
Douglas Gregor85f3f952015-07-07 03:57:15 +00006380 case Decl::ObjCTypeParam:
Guy Benyei11169dd2012-12-18 14:30:41 +00006381 return CXLanguage_ObjC;
6382 case Decl::CXXConstructor:
6383 case Decl::CXXConversion:
6384 case Decl::CXXDestructor:
6385 case Decl::CXXMethod:
6386 case Decl::CXXRecord:
6387 case Decl::ClassTemplate:
6388 case Decl::ClassTemplatePartialSpecialization:
6389 case Decl::ClassTemplateSpecialization:
6390 case Decl::Friend:
6391 case Decl::FriendTemplate:
6392 case Decl::FunctionTemplate:
6393 case Decl::LinkageSpec:
6394 case Decl::Namespace:
6395 case Decl::NamespaceAlias:
6396 case Decl::NonTypeTemplateParm:
6397 case Decl::StaticAssert:
6398 case Decl::TemplateTemplateParm:
6399 case Decl::TemplateTypeParm:
6400 case Decl::UnresolvedUsingTypename:
6401 case Decl::UnresolvedUsingValue:
6402 case Decl::Using:
6403 case Decl::UsingDirective:
6404 case Decl::UsingShadow:
6405 return CXLanguage_CPlusPlus;
6406 }
6407
6408 return CXLanguage_C;
6409}
6410
6411extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006412
6413static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6414 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
6415 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00006416
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006417 switch (D->getAvailability()) {
6418 case AR_Available:
6419 case AR_NotYetIntroduced:
6420 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006421 return getCursorAvailabilityForDecl(
6422 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006423 return CXAvailability_Available;
6424
6425 case AR_Deprecated:
6426 return CXAvailability_Deprecated;
6427
6428 case AR_Unavailable:
6429 return CXAvailability_NotAvailable;
6430 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006431
6432 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006433}
6434
Guy Benyei11169dd2012-12-18 14:30:41 +00006435enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6436 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006437 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6438 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006439
6440 return CXAvailability_Available;
6441}
6442
6443static CXVersion convertVersion(VersionTuple In) {
6444 CXVersion Out = { -1, -1, -1 };
6445 if (In.empty())
6446 return Out;
6447
6448 Out.Major = In.getMajor();
6449
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006450 Optional<unsigned> Minor = In.getMinor();
6451 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006452 Out.Minor = *Minor;
6453 else
6454 return Out;
6455
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006456 Optional<unsigned> Subminor = In.getSubminor();
6457 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006458 Out.Subminor = *Subminor;
6459
6460 return Out;
6461}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006462
6463static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6464 int *always_deprecated,
6465 CXString *deprecated_message,
6466 int *always_unavailable,
6467 CXString *unavailable_message,
6468 CXPlatformAvailability *availability,
6469 int availability_size) {
6470 bool HadAvailAttr = false;
6471 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006472 for (auto A : D->attrs()) {
6473 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006474 HadAvailAttr = true;
6475 if (always_deprecated)
6476 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006477 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006478 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006479 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006480 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006481 continue;
6482 }
6483
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006484 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006485 HadAvailAttr = true;
6486 if (always_unavailable)
6487 *always_unavailable = 1;
6488 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006489 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006490 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6491 }
6492 continue;
6493 }
6494
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006495 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006496 HadAvailAttr = true;
6497 if (N < availability_size) {
6498 availability[N].Platform
6499 = cxstring::createDup(Avail->getPlatform()->getName());
6500 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6501 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6502 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6503 availability[N].Unavailable = Avail->getUnavailable();
6504 availability[N].Message = cxstring::createDup(Avail->getMessage());
6505 }
6506 ++N;
6507 }
6508 }
6509
6510 if (!HadAvailAttr)
6511 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6512 return getCursorPlatformAvailabilityForDecl(
6513 cast<Decl>(EnumConst->getDeclContext()),
6514 always_deprecated,
6515 deprecated_message,
6516 always_unavailable,
6517 unavailable_message,
6518 availability,
6519 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006520
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006521 return N;
6522}
6523
Guy Benyei11169dd2012-12-18 14:30:41 +00006524int clang_getCursorPlatformAvailability(CXCursor cursor,
6525 int *always_deprecated,
6526 CXString *deprecated_message,
6527 int *always_unavailable,
6528 CXString *unavailable_message,
6529 CXPlatformAvailability *availability,
6530 int availability_size) {
6531 if (always_deprecated)
6532 *always_deprecated = 0;
6533 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006534 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006535 if (always_unavailable)
6536 *always_unavailable = 0;
6537 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006538 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006539
Guy Benyei11169dd2012-12-18 14:30:41 +00006540 if (!clang_isDeclaration(cursor.kind))
6541 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006542
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006543 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006544 if (!D)
6545 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006546
6547 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6548 deprecated_message,
6549 always_unavailable,
6550 unavailable_message,
6551 availability,
6552 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006553}
6554
6555void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6556 clang_disposeString(availability->Platform);
6557 clang_disposeString(availability->Message);
6558}
6559
6560CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6561 if (clang_isDeclaration(cursor.kind))
6562 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6563
6564 return CXLanguage_Invalid;
6565}
6566
6567 /// \brief If the given cursor is the "templated" declaration
6568 /// descibing a class or function template, return the class or
6569 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006570static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006571 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006572 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006573
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006574 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006575 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6576 return FunTmpl;
6577
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006578 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006579 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6580 return ClassTmpl;
6581
6582 return D;
6583}
6584
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006585
6586enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
6587 StorageClass sc = SC_None;
6588 const Decl *D = getCursorDecl(C);
6589 if (D) {
6590 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
6591 sc = FD->getStorageClass();
6592 } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
6593 sc = VD->getStorageClass();
6594 } else {
6595 return CX_SC_Invalid;
6596 }
6597 } else {
6598 return CX_SC_Invalid;
6599 }
6600 switch (sc) {
6601 case SC_None:
6602 return CX_SC_None;
6603 case SC_Extern:
6604 return CX_SC_Extern;
6605 case SC_Static:
6606 return CX_SC_Static;
6607 case SC_PrivateExtern:
6608 return CX_SC_PrivateExtern;
6609 case SC_OpenCLWorkGroupLocal:
6610 return CX_SC_OpenCLWorkGroupLocal;
6611 case SC_Auto:
6612 return CX_SC_Auto;
6613 case SC_Register:
6614 return CX_SC_Register;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006615 }
Kaelyn Takataab61e702014-10-15 18:03:26 +00006616 llvm_unreachable("Unhandled storage class!");
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006617}
6618
Guy Benyei11169dd2012-12-18 14:30:41 +00006619CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6620 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006621 if (const Decl *D = getCursorDecl(cursor)) {
6622 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006623 if (!DC)
6624 return clang_getNullCursor();
6625
6626 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6627 getCursorTU(cursor));
6628 }
6629 }
6630
6631 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006632 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006633 return MakeCXCursor(D, getCursorTU(cursor));
6634 }
6635
6636 return clang_getNullCursor();
6637}
6638
6639CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6640 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006641 if (const Decl *D = getCursorDecl(cursor)) {
6642 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006643 if (!DC)
6644 return clang_getNullCursor();
6645
6646 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6647 getCursorTU(cursor));
6648 }
6649 }
6650
6651 // FIXME: Note that we can't easily compute the lexical context of a
6652 // statement or expression, so we return nothing.
6653 return clang_getNullCursor();
6654}
6655
6656CXFile clang_getIncludedFile(CXCursor cursor) {
6657 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006658 return nullptr;
6659
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006660 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006661 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006662}
6663
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006664unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6665 if (C.kind != CXCursor_ObjCPropertyDecl)
6666 return CXObjCPropertyAttr_noattr;
6667
6668 unsigned Result = CXObjCPropertyAttr_noattr;
6669 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6670 ObjCPropertyDecl::PropertyAttributeKind Attr =
6671 PD->getPropertyAttributesAsWritten();
6672
6673#define SET_CXOBJCPROP_ATTR(A) \
6674 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6675 Result |= CXObjCPropertyAttr_##A
6676 SET_CXOBJCPROP_ATTR(readonly);
6677 SET_CXOBJCPROP_ATTR(getter);
6678 SET_CXOBJCPROP_ATTR(assign);
6679 SET_CXOBJCPROP_ATTR(readwrite);
6680 SET_CXOBJCPROP_ATTR(retain);
6681 SET_CXOBJCPROP_ATTR(copy);
6682 SET_CXOBJCPROP_ATTR(nonatomic);
6683 SET_CXOBJCPROP_ATTR(setter);
6684 SET_CXOBJCPROP_ATTR(atomic);
6685 SET_CXOBJCPROP_ATTR(weak);
6686 SET_CXOBJCPROP_ATTR(strong);
6687 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6688#undef SET_CXOBJCPROP_ATTR
6689
6690 return Result;
6691}
6692
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006693unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6694 if (!clang_isDeclaration(C.kind))
6695 return CXObjCDeclQualifier_None;
6696
6697 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6698 const Decl *D = getCursorDecl(C);
6699 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6700 QT = MD->getObjCDeclQualifier();
6701 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6702 QT = PD->getObjCDeclQualifier();
6703 if (QT == Decl::OBJC_TQ_None)
6704 return CXObjCDeclQualifier_None;
6705
6706 unsigned Result = CXObjCDeclQualifier_None;
6707 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6708 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6709 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6710 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6711 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6712 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6713
6714 return Result;
6715}
6716
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006717unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6718 if (!clang_isDeclaration(C.kind))
6719 return 0;
6720
6721 const Decl *D = getCursorDecl(C);
6722 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6723 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6724 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6725 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6726
6727 return 0;
6728}
6729
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006730unsigned clang_Cursor_isVariadic(CXCursor C) {
6731 if (!clang_isDeclaration(C.kind))
6732 return 0;
6733
6734 const Decl *D = getCursorDecl(C);
6735 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6736 return FD->isVariadic();
6737 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6738 return MD->isVariadic();
6739
6740 return 0;
6741}
6742
Guy Benyei11169dd2012-12-18 14:30:41 +00006743CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6744 if (!clang_isDeclaration(C.kind))
6745 return clang_getNullRange();
6746
6747 const Decl *D = getCursorDecl(C);
6748 ASTContext &Context = getCursorContext(C);
6749 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6750 if (!RC)
6751 return clang_getNullRange();
6752
6753 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6754}
6755
6756CXString clang_Cursor_getRawCommentText(CXCursor C) {
6757 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006758 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006759
6760 const Decl *D = getCursorDecl(C);
6761 ASTContext &Context = getCursorContext(C);
6762 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6763 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6764 StringRef();
6765
6766 // Don't duplicate the string because RawText points directly into source
6767 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006768 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006769}
6770
6771CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6772 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006773 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006774
6775 const Decl *D = getCursorDecl(C);
6776 const ASTContext &Context = getCursorContext(C);
6777 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6778
6779 if (RC) {
6780 StringRef BriefText = RC->getBriefText(Context);
6781
6782 // Don't duplicate the string because RawComment ensures that this memory
6783 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006784 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006785 }
6786
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006787 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006788}
6789
Guy Benyei11169dd2012-12-18 14:30:41 +00006790CXModule clang_Cursor_getModule(CXCursor C) {
6791 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006792 if (const ImportDecl *ImportD =
6793 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006794 return ImportD->getImportedModule();
6795 }
6796
Craig Topper69186e72014-06-08 08:38:04 +00006797 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006798}
6799
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006800CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6801 if (isNotUsableTU(TU)) {
6802 LOG_BAD_TU(TU);
6803 return nullptr;
6804 }
6805 if (!File)
6806 return nullptr;
6807 FileEntry *FE = static_cast<FileEntry *>(File);
6808
6809 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6810 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6811 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6812
Richard Smithfeb54b62014-10-23 02:01:19 +00006813 return Header.getModule();
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006814}
6815
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006816CXFile clang_Module_getASTFile(CXModule CXMod) {
6817 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006818 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006819 Module *Mod = static_cast<Module*>(CXMod);
6820 return const_cast<FileEntry *>(Mod->getASTFile());
6821}
6822
Guy Benyei11169dd2012-12-18 14:30:41 +00006823CXModule clang_Module_getParent(CXModule CXMod) {
6824 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006825 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006826 Module *Mod = static_cast<Module*>(CXMod);
6827 return Mod->Parent;
6828}
6829
6830CXString clang_Module_getName(CXModule CXMod) {
6831 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006832 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006833 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006834 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006835}
6836
6837CXString clang_Module_getFullName(CXModule CXMod) {
6838 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006839 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006840 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006841 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006842}
6843
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006844int clang_Module_isSystem(CXModule CXMod) {
6845 if (!CXMod)
6846 return 0;
6847 Module *Mod = static_cast<Module*>(CXMod);
6848 return Mod->IsSystem;
6849}
6850
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006851unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6852 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006853 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006854 LOG_BAD_TU(TU);
6855 return 0;
6856 }
6857 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006858 return 0;
6859 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006860 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6861 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6862 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006863}
6864
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006865CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6866 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006867 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006868 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006869 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006870 }
6871 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006872 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006873 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006874 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006875
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006876 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6877 if (Index < TopHeaders.size())
6878 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006879
Craig Topper69186e72014-06-08 08:38:04 +00006880 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006881}
6882
6883} // end: extern "C"
6884
6885//===----------------------------------------------------------------------===//
6886// C++ AST instrospection.
6887//===----------------------------------------------------------------------===//
6888
6889extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006890unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6891 if (!clang_isDeclaration(C.kind))
6892 return 0;
6893
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006894 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006895 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006896 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006897 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6898}
6899
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006900unsigned clang_CXXMethod_isConst(CXCursor C) {
6901 if (!clang_isDeclaration(C.kind))
6902 return 0;
6903
6904 const Decl *D = cxcursor::getCursorDecl(C);
6905 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006906 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006907 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6908}
6909
Guy Benyei11169dd2012-12-18 14:30:41 +00006910unsigned clang_CXXMethod_isStatic(CXCursor C) {
6911 if (!clang_isDeclaration(C.kind))
6912 return 0;
6913
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006914 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006915 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006916 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006917 return (Method && Method->isStatic()) ? 1 : 0;
6918}
6919
6920unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6921 if (!clang_isDeclaration(C.kind))
6922 return 0;
6923
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006924 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006925 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006926 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006927 return (Method && Method->isVirtual()) ? 1 : 0;
6928}
6929} // end: extern "C"
6930
6931//===----------------------------------------------------------------------===//
6932// Attribute introspection.
6933//===----------------------------------------------------------------------===//
6934
6935extern "C" {
6936CXType clang_getIBOutletCollectionType(CXCursor C) {
6937 if (C.kind != CXCursor_IBOutletCollectionAttr)
6938 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6939
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006940 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006941 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6942
6943 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6944}
6945} // end: extern "C"
6946
6947//===----------------------------------------------------------------------===//
6948// Inspecting memory usage.
6949//===----------------------------------------------------------------------===//
6950
6951typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6952
6953static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6954 enum CXTUResourceUsageKind k,
6955 unsigned long amount) {
6956 CXTUResourceUsageEntry entry = { k, amount };
6957 entries.push_back(entry);
6958}
6959
6960extern "C" {
6961
6962const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6963 const char *str = "";
6964 switch (kind) {
6965 case CXTUResourceUsage_AST:
6966 str = "ASTContext: expressions, declarations, and types";
6967 break;
6968 case CXTUResourceUsage_Identifiers:
6969 str = "ASTContext: identifiers";
6970 break;
6971 case CXTUResourceUsage_Selectors:
6972 str = "ASTContext: selectors";
6973 break;
6974 case CXTUResourceUsage_GlobalCompletionResults:
6975 str = "Code completion: cached global results";
6976 break;
6977 case CXTUResourceUsage_SourceManagerContentCache:
6978 str = "SourceManager: content cache allocator";
6979 break;
6980 case CXTUResourceUsage_AST_SideTables:
6981 str = "ASTContext: side tables";
6982 break;
6983 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6984 str = "SourceManager: malloc'ed memory buffers";
6985 break;
6986 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6987 str = "SourceManager: mmap'ed memory buffers";
6988 break;
6989 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6990 str = "ExternalASTSource: malloc'ed memory buffers";
6991 break;
6992 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6993 str = "ExternalASTSource: mmap'ed memory buffers";
6994 break;
6995 case CXTUResourceUsage_Preprocessor:
6996 str = "Preprocessor: malloc'ed memory";
6997 break;
6998 case CXTUResourceUsage_PreprocessingRecord:
6999 str = "Preprocessor: PreprocessingRecord";
7000 break;
7001 case CXTUResourceUsage_SourceManager_DataStructures:
7002 str = "SourceManager: data structures and tables";
7003 break;
7004 case CXTUResourceUsage_Preprocessor_HeaderSearch:
7005 str = "Preprocessor: header search tables";
7006 break;
7007 }
7008 return str;
7009}
7010
7011CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007012 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007013 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00007014 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00007015 return usage;
7016 }
7017
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007018 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00007019 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00007020 ASTContext &astContext = astUnit->getASTContext();
7021
7022 // How much memory is used by AST nodes and types?
7023 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
7024 (unsigned long) astContext.getASTAllocatedMemory());
7025
7026 // How much memory is used by identifiers?
7027 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
7028 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
7029
7030 // How much memory is used for selectors?
7031 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
7032 (unsigned long) astContext.Selectors.getTotalMemory());
7033
7034 // How much memory is used by ASTContext's side tables?
7035 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
7036 (unsigned long) astContext.getSideTableAllocatedMemory());
7037
7038 // How much memory is used for caching global code completion results?
7039 unsigned long completionBytes = 0;
7040 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00007041 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007042 completionBytes = completionAllocator->getTotalMemory();
7043 }
7044 createCXTUResourceUsageEntry(*entries,
7045 CXTUResourceUsage_GlobalCompletionResults,
7046 completionBytes);
7047
7048 // How much memory is being used by SourceManager's content cache?
7049 createCXTUResourceUsageEntry(*entries,
7050 CXTUResourceUsage_SourceManagerContentCache,
7051 (unsigned long) astContext.getSourceManager().getContentCacheSize());
7052
7053 // How much memory is being used by the MemoryBuffer's in SourceManager?
7054 const SourceManager::MemoryBufferSizes &srcBufs =
7055 astUnit->getSourceManager().getMemoryBufferSizes();
7056
7057 createCXTUResourceUsageEntry(*entries,
7058 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
7059 (unsigned long) srcBufs.malloc_bytes);
7060 createCXTUResourceUsageEntry(*entries,
7061 CXTUResourceUsage_SourceManager_Membuffer_MMap,
7062 (unsigned long) srcBufs.mmap_bytes);
7063 createCXTUResourceUsageEntry(*entries,
7064 CXTUResourceUsage_SourceManager_DataStructures,
7065 (unsigned long) astContext.getSourceManager()
7066 .getDataStructureSizes());
7067
7068 // How much memory is being used by the ExternalASTSource?
7069 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
7070 const ExternalASTSource::MemoryBufferSizes &sizes =
7071 esrc->getMemoryBufferSizes();
7072
7073 createCXTUResourceUsageEntry(*entries,
7074 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
7075 (unsigned long) sizes.malloc_bytes);
7076 createCXTUResourceUsageEntry(*entries,
7077 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
7078 (unsigned long) sizes.mmap_bytes);
7079 }
7080
7081 // How much memory is being used by the Preprocessor?
7082 Preprocessor &pp = astUnit->getPreprocessor();
7083 createCXTUResourceUsageEntry(*entries,
7084 CXTUResourceUsage_Preprocessor,
7085 pp.getTotalMemory());
7086
7087 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
7088 createCXTUResourceUsageEntry(*entries,
7089 CXTUResourceUsage_PreprocessingRecord,
7090 pRec->getTotalMemory());
7091 }
7092
7093 createCXTUResourceUsageEntry(*entries,
7094 CXTUResourceUsage_Preprocessor_HeaderSearch,
7095 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00007096
Guy Benyei11169dd2012-12-18 14:30:41 +00007097 CXTUResourceUsage usage = { (void*) entries.get(),
7098 (unsigned) entries->size(),
Alexander Kornienko6ee521c2015-01-23 15:36:10 +00007099 !entries->empty() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00007100 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00007101 return usage;
7102}
7103
7104void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
7105 if (usage.data)
7106 delete (MemUsageEntries*) usage.data;
7107}
7108
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007109CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
7110 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007111 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00007112 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007113
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007114 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007115 LOG_BAD_TU(TU);
7116 return skipped;
7117 }
7118
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007119 if (!file)
7120 return skipped;
7121
7122 ASTUnit *astUnit = cxtu::getASTUnit(TU);
7123 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
7124 if (!ppRec)
7125 return skipped;
7126
7127 ASTContext &Ctx = astUnit->getASTContext();
7128 SourceManager &sm = Ctx.getSourceManager();
7129 FileEntry *fileEntry = static_cast<FileEntry *>(file);
7130 FileID wantedFileID = sm.translateFile(fileEntry);
7131
7132 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
7133 std::vector<SourceRange> wantedRanges;
7134 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
7135 i != ei; ++i) {
7136 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
7137 wantedRanges.push_back(*i);
7138 }
7139
7140 skipped->count = wantedRanges.size();
7141 skipped->ranges = new CXSourceRange[skipped->count];
7142 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
7143 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
7144
7145 return skipped;
7146}
7147
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007148void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
7149 if (ranges) {
7150 delete[] ranges->ranges;
7151 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007152 }
7153}
7154
Guy Benyei11169dd2012-12-18 14:30:41 +00007155} // end extern "C"
7156
7157void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
7158 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
7159 for (unsigned I = 0; I != Usage.numEntries; ++I)
7160 fprintf(stderr, " %s: %lu\n",
7161 clang_getTUResourceUsageName(Usage.entries[I].kind),
7162 Usage.entries[I].amount);
7163
7164 clang_disposeCXTUResourceUsage(Usage);
7165}
7166
7167//===----------------------------------------------------------------------===//
7168// Misc. utility functions.
7169//===----------------------------------------------------------------------===//
7170
7171/// Default to using an 8 MB stack size on "safety" threads.
7172static unsigned SafetyStackThreadSize = 8 << 20;
7173
7174namespace clang {
7175
7176bool RunSafely(llvm::CrashRecoveryContext &CRC,
7177 void (*Fn)(void*), void *UserData,
7178 unsigned Size) {
7179 if (!Size)
7180 Size = GetSafetyThreadStackSize();
7181 if (Size)
7182 return CRC.RunSafelyOnThread(Fn, UserData, Size);
7183 return CRC.RunSafely(Fn, UserData);
7184}
7185
7186unsigned GetSafetyThreadStackSize() {
7187 return SafetyStackThreadSize;
7188}
7189
7190void SetSafetyThreadStackSize(unsigned Value) {
7191 SafetyStackThreadSize = Value;
7192}
7193
Alexander Kornienkoab9db512015-06-22 23:07:51 +00007194}
Guy Benyei11169dd2012-12-18 14:30:41 +00007195
7196void clang::setThreadBackgroundPriority() {
7197 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
7198 return;
7199
Alp Toker1a86ad22014-07-06 06:24:00 +00007200#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00007201 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
7202#endif
7203}
7204
7205void cxindex::printDiagsToStderr(ASTUnit *Unit) {
7206 if (!Unit)
7207 return;
7208
7209 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
7210 DEnd = Unit->stored_diag_end();
7211 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00007212 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00007213 CXString Msg = clang_formatDiagnostic(&Diag,
7214 clang_defaultDiagnosticDisplayOptions());
7215 fprintf(stderr, "%s\n", clang_getCString(Msg));
7216 clang_disposeString(Msg);
7217 }
7218#ifdef LLVM_ON_WIN32
7219 // On Windows, force a flush, since there may be multiple copies of
7220 // stderr and stdout in the file system, all with different buffers
7221 // but writing to the same device.
7222 fflush(stderr);
7223#endif
7224}
7225
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007226MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
7227 SourceLocation MacroDefLoc,
7228 CXTranslationUnit TU){
7229 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007230 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007231 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007232 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007233
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007234 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007235 Preprocessor &PP = Unit->getPreprocessor();
Richard Smith20e883e2015-04-29 23:20:19 +00007236 MacroDirective *MD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007237 if (MD) {
7238 for (MacroDirective::DefInfo
7239 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
7240 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
7241 return Def.getMacroInfo();
7242 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007243 }
7244
Craig Topper69186e72014-06-08 08:38:04 +00007245 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007246}
7247
Richard Smith66a81862015-05-04 02:25:31 +00007248const MacroInfo *cxindex::getMacroInfo(const MacroDefinitionRecord *MacroDef,
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007249 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007250 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007251 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007252 const IdentifierInfo *II = MacroDef->getName();
7253 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00007254 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007255
7256 return getMacroInfo(*II, MacroDef->getLocation(), TU);
7257}
7258
Richard Smith66a81862015-05-04 02:25:31 +00007259MacroDefinitionRecord *
7260cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, const Token &Tok,
7261 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007262 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007263 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007264 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00007265 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007266
7267 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007268 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007269 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
7270 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007271 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007272
7273 // Check that the token is inside the definition and not its argument list.
7274 SourceManager &SM = Unit->getSourceManager();
7275 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00007276 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007277 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00007278 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007279
7280 Preprocessor &PP = Unit->getPreprocessor();
7281 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
7282 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00007283 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007284
Alp Toker2d57cea2014-05-17 04:53:25 +00007285 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007286 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007287 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007288
7289 // Check that the identifier is not one of the macro arguments.
7290 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00007291 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007292
Richard Smith20e883e2015-04-29 23:20:19 +00007293 MacroDirective *InnerMD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007294 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00007295 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007296
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007297 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007298}
7299
Richard Smith66a81862015-05-04 02:25:31 +00007300MacroDefinitionRecord *
7301cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, SourceLocation Loc,
7302 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007303 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007304 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007305
7306 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007307 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007308 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007309 Preprocessor &PP = Unit->getPreprocessor();
7310 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00007311 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007312 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7313 Token Tok;
7314 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00007315 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007316
7317 return checkForMacroInMacroDefinition(MI, Tok, TU);
7318}
7319
Guy Benyei11169dd2012-12-18 14:30:41 +00007320extern "C" {
7321
7322CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007323 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00007324}
7325
7326} // end: extern "C"
7327
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007328Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7329 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007330 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007331 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007332 if (Unit->isMainFileAST())
7333 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007334 return *this;
7335 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007336 } else {
7337 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007338 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007339 return *this;
7340}
7341
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007342Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7343 *this << FE->getName();
7344 return *this;
7345}
7346
7347Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7348 CXString cursorName = clang_getCursorDisplayName(cursor);
7349 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7350 clang_disposeString(cursorName);
7351 return *this;
7352}
7353
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007354Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7355 CXFile File;
7356 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007357 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007358 CXString FileName = clang_getFileName(File);
7359 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7360 clang_disposeString(FileName);
7361 return *this;
7362}
7363
7364Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7365 CXSourceLocation BLoc = clang_getRangeStart(range);
7366 CXSourceLocation ELoc = clang_getRangeEnd(range);
7367
7368 CXFile BFile;
7369 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007370 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007371
7372 CXFile EFile;
7373 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007374 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007375
7376 CXString BFileName = clang_getFileName(BFile);
7377 if (BFile == EFile) {
7378 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7379 BLine, BColumn, ELine, EColumn);
7380 } else {
7381 CXString EFileName = clang_getFileName(EFile);
7382 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7383 BLine, BColumn)
7384 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7385 ELine, EColumn);
7386 clang_disposeString(EFileName);
7387 }
7388 clang_disposeString(BFileName);
7389 return *this;
7390}
7391
7392Logger &cxindex::Logger::operator<<(CXString Str) {
7393 *this << clang_getCString(Str);
7394 return *this;
7395}
7396
7397Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7398 LogOS << Fmt;
7399 return *this;
7400}
7401
Chandler Carruth37ad2582014-06-27 15:14:39 +00007402static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7403
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007404cxindex::Logger::~Logger() {
7405 LogOS.flush();
7406
Chandler Carruth37ad2582014-06-27 15:14:39 +00007407 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007408
7409 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7410
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007411 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007412 OS << "[libclang:" << Name << ':';
7413
Alp Toker1a86ad22014-07-06 06:24:00 +00007414#ifdef USE_DARWIN_THREADS
7415 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007416 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7417 OS << tid << ':';
7418#endif
7419
7420 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7421 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
Yaron Keren09fb7c62015-03-10 07:33:23 +00007422 OS << Msg << '\n';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007423
7424 if (Trace) {
Zachary Turner1fe2a8d2015-03-05 19:15:09 +00007425 llvm::sys::PrintStackTrace(OS);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007426 OS << "--------------------------------------------------\n";
7427 }
7428}