blob: 6ea379a8cd1c579d45c224ceb46ce413e36df5d5 [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"
Guy Benyei11169dd2012-12-18 14:30:41 +000025#include "clang/AST/StmtVisitor.h"
26#include "clang/Basic/Diagnostic.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000027#include "clang/Basic/DiagnosticCategories.h"
28#include "clang/Basic/DiagnosticIDs.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000029#include "clang/Basic/Version.h"
30#include "clang/Frontend/ASTUnit.h"
31#include "clang/Frontend/CompilerInstance.h"
32#include "clang/Frontend/FrontendDiagnostic.h"
Argyrios Kyrtzidisca741ce2016-02-14 22:30:14 +000033#include "clang/Index/CodegenNameGenerator.h"
Dmitri Gribenko9e605112013-11-13 22:16:51 +000034#include "clang/Index/CommentToXML.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000035#include "clang/Lex/HeaderSearch.h"
36#include "clang/Lex/Lexer.h"
37#include "clang/Lex/PreprocessingRecord.h"
38#include "clang/Lex/Preprocessor.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000039#include "clang/Serialization/SerializationDiagnostic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000040#include "llvm/ADT/Optional.h"
41#include "llvm/ADT/STLExtras.h"
42#include "llvm/ADT/StringSwitch.h"
Alp Toker1d257e12014-06-04 03:28:55 +000043#include "llvm/Config/llvm-config.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000044#include "llvm/Support/Compiler.h"
45#include "llvm/Support/CrashRecoveryContext.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000046#include "llvm/Support/Format.h"
Chandler Carruth37ad2582014-06-27 15:14:39 +000047#include "llvm/Support/ManagedStatic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000048#include "llvm/Support/MemoryBuffer.h"
49#include "llvm/Support/Mutex.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000050#include "llvm/Support/Program.h"
51#include "llvm/Support/SaveAndRestore.h"
52#include "llvm/Support/Signals.h"
Adrian Prantlbc068582015-07-08 01:00:30 +000053#include "llvm/Support/TargetSelect.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000054#include "llvm/Support/Threading.h"
55#include "llvm/Support/Timer.h"
56#include "llvm/Support/raw_ostream.h"
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000057
Alp Toker1a86ad22014-07-06 06:24:00 +000058#if LLVM_ENABLE_THREADS != 0 && defined(__APPLE__)
59#define USE_DARWIN_THREADS
60#endif
61
62#ifdef USE_DARWIN_THREADS
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000063#include <pthread.h>
64#endif
Guy Benyei11169dd2012-12-18 14:30:41 +000065
66using namespace clang;
67using namespace clang::cxcursor;
Guy Benyei11169dd2012-12-18 14:30:41 +000068using namespace clang::cxtu;
69using namespace clang::cxindex;
70
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000071CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) {
72 if (!AU)
Craig Topper69186e72014-06-08 08:38:04 +000073 return nullptr;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000074 assert(CIdx);
Guy Benyei11169dd2012-12-18 14:30:41 +000075 CXTranslationUnit D = new CXTranslationUnitImpl();
76 D->CIdx = CIdx;
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000077 D->TheASTUnit = AU;
Dmitri Gribenko74895212013-02-03 13:52:47 +000078 D->StringPool = new cxstring::CXStringPool();
Craig Topper69186e72014-06-08 08:38:04 +000079 D->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000080 D->OverridenCursorsPool = createOverridenCXCursorsPool();
Craig Topper69186e72014-06-08 08:38:04 +000081 D->CommentToXML = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000082 return D;
83}
84
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000085bool cxtu::isASTReadError(ASTUnit *AU) {
86 for (ASTUnit::stored_diag_iterator D = AU->stored_diag_begin(),
87 DEnd = AU->stored_diag_end();
88 D != DEnd; ++D) {
89 if (D->getLevel() >= DiagnosticsEngine::Error &&
90 DiagnosticIDs::getCategoryNumberForDiag(D->getID()) ==
91 diag::DiagCat_AST_Deserialization_Issue)
92 return true;
93 }
94 return false;
95}
96
Guy Benyei11169dd2012-12-18 14:30:41 +000097cxtu::CXTUOwner::~CXTUOwner() {
98 if (TU)
99 clang_disposeTranslationUnit(TU);
100}
101
102/// \brief Compare two source ranges to determine their relative position in
103/// the translation unit.
104static RangeComparisonResult RangeCompare(SourceManager &SM,
105 SourceRange R1,
106 SourceRange R2) {
107 assert(R1.isValid() && "First range is invalid?");
108 assert(R2.isValid() && "Second range is invalid?");
109 if (R1.getEnd() != R2.getBegin() &&
110 SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
111 return RangeBefore;
112 if (R2.getEnd() != R1.getBegin() &&
113 SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
114 return RangeAfter;
115 return RangeOverlap;
116}
117
118/// \brief Determine if a source location falls within, before, or after a
119/// a given source range.
120static RangeComparisonResult LocationCompare(SourceManager &SM,
121 SourceLocation L, SourceRange R) {
122 assert(R.isValid() && "First range is invalid?");
123 assert(L.isValid() && "Second range is invalid?");
124 if (L == R.getBegin() || L == R.getEnd())
125 return RangeOverlap;
126 if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
127 return RangeBefore;
128 if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
129 return RangeAfter;
130 return RangeOverlap;
131}
132
133/// \brief Translate a Clang source range into a CIndex source range.
134///
135/// Clang internally represents ranges where the end location points to the
136/// start of the token at the end. However, for external clients it is more
137/// useful to have a CXSourceRange be a proper half-open interval. This routine
138/// does the appropriate translation.
139CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
140 const LangOptions &LangOpts,
141 const CharSourceRange &R) {
142 // We want the last character in this location, so we will adjust the
143 // location accordingly.
144 SourceLocation EndLoc = R.getEnd();
145 if (EndLoc.isValid() && EndLoc.isMacroID() && !SM.isMacroArgExpansion(EndLoc))
146 EndLoc = SM.getExpansionRange(EndLoc).second;
Yaron Keren8b563662015-10-03 10:46:20 +0000147 if (R.isTokenRange() && EndLoc.isValid()) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000148 unsigned Length = Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc),
149 SM, LangOpts);
150 EndLoc = EndLoc.getLocWithOffset(Length);
151 }
152
Bill Wendlingeade3622013-01-23 08:25:41 +0000153 CXSourceRange Result = {
Dmitri Gribenkof9304482013-01-23 15:56:07 +0000154 { &SM, &LangOpts },
Bill Wendlingeade3622013-01-23 08:25:41 +0000155 R.getBegin().getRawEncoding(),
156 EndLoc.getRawEncoding()
157 };
Guy Benyei11169dd2012-12-18 14:30:41 +0000158 return Result;
159}
160
161//===----------------------------------------------------------------------===//
162// Cursor visitor.
163//===----------------------------------------------------------------------===//
164
165static SourceRange getRawCursorExtent(CXCursor C);
166static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
167
168
169RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
170 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
171}
172
173/// \brief Visit the given cursor and, if requested by the visitor,
174/// its children.
175///
176/// \param Cursor the cursor to visit.
177///
178/// \param CheckedRegionOfInterest if true, then the caller already checked
179/// that this cursor is within the region of interest.
180///
181/// \returns true if the visitation should be aborted, false if it
182/// should continue.
183bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
184 if (clang_isInvalid(Cursor.kind))
185 return false;
186
187 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000188 const Decl *D = getCursorDecl(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000189 if (!D) {
190 assert(0 && "Invalid declaration cursor");
191 return true; // abort.
192 }
193
194 // Ignore implicit declarations, unless it's an objc method because
195 // currently we should report implicit methods for properties when indexing.
196 if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
197 return false;
198 }
199
200 // If we have a range of interest, and this cursor doesn't intersect with it,
201 // we're done.
202 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
203 SourceRange Range = getRawCursorExtent(Cursor);
204 if (Range.isInvalid() || CompareRegionOfInterest(Range))
205 return false;
206 }
207
208 switch (Visitor(Cursor, Parent, ClientData)) {
209 case CXChildVisit_Break:
210 return true;
211
212 case CXChildVisit_Continue:
213 return false;
214
215 case CXChildVisit_Recurse: {
216 bool ret = VisitChildren(Cursor);
217 if (PostChildrenVisitor)
218 if (PostChildrenVisitor(Cursor, ClientData))
219 return true;
220 return ret;
221 }
222 }
223
224 llvm_unreachable("Invalid CXChildVisitResult!");
225}
226
227static bool visitPreprocessedEntitiesInRange(SourceRange R,
228 PreprocessingRecord &PPRec,
229 CursorVisitor &Visitor) {
230 SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
231 FileID FID;
232
233 if (!Visitor.shouldVisitIncludedEntities()) {
234 // If the begin/end of the range lie in the same FileID, do the optimization
235 // where we skip preprocessed entities that do not come from the same FileID.
236 FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
237 if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
238 FID = FileID();
239 }
240
Benjamin Kramerb4ef6682015-02-06 17:25:10 +0000241 const auto &Entities = PPRec.getPreprocessedEntitiesInRange(R);
242 return Visitor.visitPreprocessedEntities(Entities.begin(), Entities.end(),
Guy Benyei11169dd2012-12-18 14:30:41 +0000243 PPRec, FID);
244}
245
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000246bool CursorVisitor::visitFileRegion() {
Guy Benyei11169dd2012-12-18 14:30:41 +0000247 if (RegionOfInterest.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000248 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000249
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000250 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000251 SourceManager &SM = Unit->getSourceManager();
252
253 std::pair<FileID, unsigned>
254 Begin = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getBegin())),
255 End = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getEnd()));
256
257 if (End.first != Begin.first) {
258 // If the end does not reside in the same file, try to recover by
259 // picking the end of the file of begin location.
260 End.first = Begin.first;
261 End.second = SM.getFileIDSize(Begin.first);
262 }
263
264 assert(Begin.first == End.first);
265 if (Begin.second > End.second)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000266 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000267
268 FileID File = Begin.first;
269 unsigned Offset = Begin.second;
270 unsigned Length = End.second - Begin.second;
271
272 if (!VisitDeclsOnly && !VisitPreprocessorLast)
273 if (visitPreprocessedEntitiesInRegion())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000274 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000275
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000276 if (visitDeclsFromFileRegion(File, Offset, Length))
277 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000278
279 if (!VisitDeclsOnly && VisitPreprocessorLast)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000280 return visitPreprocessedEntitiesInRegion();
281
282 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000283}
284
285static bool isInLexicalContext(Decl *D, DeclContext *DC) {
286 if (!DC)
287 return false;
288
289 for (DeclContext *DeclDC = D->getLexicalDeclContext();
290 DeclDC; DeclDC = DeclDC->getLexicalParent()) {
291 if (DeclDC == DC)
292 return true;
293 }
294 return false;
295}
296
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000297bool CursorVisitor::visitDeclsFromFileRegion(FileID File,
Guy Benyei11169dd2012-12-18 14:30:41 +0000298 unsigned Offset, unsigned Length) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000299 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000300 SourceManager &SM = Unit->getSourceManager();
301 SourceRange Range = RegionOfInterest;
302
303 SmallVector<Decl *, 16> Decls;
304 Unit->findFileRegionDecls(File, Offset, Length, Decls);
305
306 // If we didn't find any file level decls for the file, try looking at the
307 // file that it was included from.
308 while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
309 bool Invalid = false;
310 const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
311 if (Invalid)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000312 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000313
314 SourceLocation Outer;
315 if (SLEntry.isFile())
316 Outer = SLEntry.getFile().getIncludeLoc();
317 else
318 Outer = SLEntry.getExpansion().getExpansionLocStart();
319 if (Outer.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000320 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000321
Benjamin Kramer867ea1d2014-03-02 13:01:17 +0000322 std::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
Guy Benyei11169dd2012-12-18 14:30:41 +0000323 Length = 0;
324 Unit->findFileRegionDecls(File, Offset, Length, Decls);
325 }
326
327 assert(!Decls.empty());
328
329 bool VisitedAtLeastOnce = false;
Craig Topper69186e72014-06-08 08:38:04 +0000330 DeclContext *CurDC = nullptr;
Craig Topper2341c0d2013-07-04 03:08:24 +0000331 SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
332 for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000333 Decl *D = *DIt;
334 if (D->getSourceRange().isInvalid())
335 continue;
336
337 if (isInLexicalContext(D, CurDC))
338 continue;
339
340 CurDC = dyn_cast<DeclContext>(D);
341
342 if (TagDecl *TD = dyn_cast<TagDecl>(D))
343 if (!TD->isFreeStanding())
344 continue;
345
346 RangeComparisonResult CompRes = RangeCompare(SM, D->getSourceRange(),Range);
347 if (CompRes == RangeBefore)
348 continue;
349 if (CompRes == RangeAfter)
350 break;
351
352 assert(CompRes == RangeOverlap);
353 VisitedAtLeastOnce = true;
354
355 if (isa<ObjCContainerDecl>(D)) {
356 FileDI_current = &DIt;
357 FileDE_current = DE;
358 } else {
Craig Topper69186e72014-06-08 08:38:04 +0000359 FileDI_current = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +0000360 }
361
362 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000363 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000364 }
365
366 if (VisitedAtLeastOnce)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000367 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000368
369 // No Decls overlapped with the range. Move up the lexical context until there
370 // is a context that contains the range or we reach the translation unit
371 // level.
372 DeclContext *DC = DIt == Decls.begin() ? (*DIt)->getLexicalDeclContext()
373 : (*(DIt-1))->getLexicalDeclContext();
374
375 while (DC && !DC->isTranslationUnit()) {
376 Decl *D = cast<Decl>(DC);
377 SourceRange CurDeclRange = D->getSourceRange();
378 if (CurDeclRange.isInvalid())
379 break;
380
381 if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000382 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
383 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000384 }
385
386 DC = D->getLexicalDeclContext();
387 }
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000388
389 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000390}
391
392bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
393 if (!AU->getPreprocessor().getPreprocessingRecord())
394 return false;
395
396 PreprocessingRecord &PPRec
397 = *AU->getPreprocessor().getPreprocessingRecord();
398 SourceManager &SM = AU->getSourceManager();
399
400 if (RegionOfInterest.isValid()) {
401 SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
402 SourceLocation B = MappedRange.getBegin();
403 SourceLocation E = MappedRange.getEnd();
404
405 if (AU->isInPreambleFileID(B)) {
406 if (SM.isLoadedSourceLocation(E))
407 return visitPreprocessedEntitiesInRange(SourceRange(B, E),
408 PPRec, *this);
409
410 // Beginning of range lies in the preamble but it also extends beyond
411 // it into the main file. Split the range into 2 parts, one covering
412 // the preamble and another covering the main file. This allows subsequent
413 // calls to visitPreprocessedEntitiesInRange to accept a source range that
414 // lies in the same FileID, allowing it to skip preprocessed entities that
415 // do not come from the same FileID.
416 bool breaked =
417 visitPreprocessedEntitiesInRange(
418 SourceRange(B, AU->getEndOfPreambleFileID()),
419 PPRec, *this);
420 if (breaked) return true;
421 return visitPreprocessedEntitiesInRange(
422 SourceRange(AU->getStartOfMainFileID(), E),
423 PPRec, *this);
424 }
425
426 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
427 }
428
429 bool OnlyLocalDecls
430 = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
431
432 if (OnlyLocalDecls)
433 return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
434 PPRec);
435
436 return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
437}
438
439template<typename InputIterator>
440bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
441 InputIterator Last,
442 PreprocessingRecord &PPRec,
443 FileID FID) {
444 for (; First != Last; ++First) {
445 if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
446 continue;
447
448 PreprocessedEntity *PPE = *First;
Argyrios Kyrtzidis1030f262013-05-07 20:37:17 +0000449 if (!PPE)
450 continue;
451
Guy Benyei11169dd2012-12-18 14:30:41 +0000452 if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
453 if (Visit(MakeMacroExpansionCursor(ME, TU)))
454 return true;
Richard Smith66a81862015-05-04 02:25:31 +0000455
Guy Benyei11169dd2012-12-18 14:30:41 +0000456 continue;
457 }
Richard Smith66a81862015-05-04 02:25:31 +0000458
459 if (MacroDefinitionRecord *MD = dyn_cast<MacroDefinitionRecord>(PPE)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000460 if (Visit(MakeMacroDefinitionCursor(MD, TU)))
461 return true;
Richard Smith66a81862015-05-04 02:25:31 +0000462
Guy Benyei11169dd2012-12-18 14:30:41 +0000463 continue;
464 }
465
466 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
467 if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
468 return true;
469
470 continue;
471 }
472 }
473
474 return false;
475}
476
477/// \brief Visit the children of the given cursor.
478///
479/// \returns true if the visitation should be aborted, false if it
480/// should continue.
481bool CursorVisitor::VisitChildren(CXCursor Cursor) {
482 if (clang_isReference(Cursor.kind) &&
483 Cursor.kind != CXCursor_CXXBaseSpecifier) {
484 // By definition, references have no children.
485 return false;
486 }
487
488 // Set the Parent field to Cursor, then back to its old value once we're
489 // done.
490 SetParentRAII SetParent(Parent, StmtParent, Cursor);
491
492 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000493 Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +0000494 if (!D)
495 return false;
496
497 return VisitAttributes(D) || Visit(D);
498 }
499
500 if (clang_isStatement(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000501 if (const Stmt *S = getCursorStmt(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000502 return Visit(S);
503
504 return false;
505 }
506
507 if (clang_isExpression(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000508 if (const Expr *E = getCursorExpr(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000509 return Visit(E);
510
511 return false;
512 }
513
514 if (clang_isTranslationUnit(Cursor.kind)) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000515 CXTranslationUnit TU = getCursorTU(Cursor);
516 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000517
518 int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
519 for (unsigned I = 0; I != 2; ++I) {
520 if (VisitOrder[I]) {
521 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
522 RegionOfInterest.isInvalid()) {
523 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
524 TLEnd = CXXUnit->top_level_end();
525 TL != TLEnd; ++TL) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000526 if (Visit(MakeCXCursor(*TL, TU, RegionOfInterest), true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000527 return true;
528 }
529 } else if (VisitDeclContext(
530 CXXUnit->getASTContext().getTranslationUnitDecl()))
531 return true;
532 continue;
533 }
534
535 // Walk the preprocessing record.
536 if (CXXUnit->getPreprocessor().getPreprocessingRecord())
537 visitPreprocessedEntitiesInRegion();
538 }
539
540 return false;
541 }
542
543 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000544 if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000545 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
546 return Visit(BaseTSInfo->getTypeLoc());
547 }
548 }
549 }
550
551 if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +0000552 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +0000553 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
Richard Smithb1f9a282013-10-31 01:56:18 +0000554 if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())
Richard Smithb87c4652013-10-31 21:23:20 +0000555 return Visit(cxcursor::MakeCursorObjCClassRef(
556 ObjT->getInterface(),
557 A->getInterfaceLoc()->getTypeLoc().getLocStart(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +0000558 }
559
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000560 // If pointing inside a macro definition, check if the token is an identifier
561 // that was ever defined as a macro. In such a case, create a "pseudo" macro
562 // expansion cursor for that token.
563 SourceLocation BeginLoc = RegionOfInterest.getBegin();
564 if (Cursor.kind == CXCursor_MacroDefinition &&
565 BeginLoc == RegionOfInterest.getEnd()) {
566 SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000567 const MacroInfo *MI =
568 getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
Richard Smith66a81862015-05-04 02:25:31 +0000569 if (MacroDefinitionRecord *MacroDef =
570 checkForMacroInMacroDefinition(MI, Loc, TU))
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000571 return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
572 }
573
Guy Benyei11169dd2012-12-18 14:30:41 +0000574 // Nothing to visit at the moment.
575 return false;
576}
577
578bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
579 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
580 if (Visit(TSInfo->getTypeLoc()))
581 return true;
582
583 if (Stmt *Body = B->getBody())
584 return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
585
586 return false;
587}
588
Ted Kremenek03325582013-02-21 01:29:01 +0000589Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000590 if (RegionOfInterest.isValid()) {
591 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
592 if (Range.isInvalid())
David Blaikie7a30dc52013-02-21 01:47:18 +0000593 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000594
595 switch (CompareRegionOfInterest(Range)) {
596 case RangeBefore:
597 // This declaration comes before the region of interest; skip it.
David Blaikie7a30dc52013-02-21 01:47:18 +0000598 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000599
600 case RangeAfter:
601 // This declaration comes after the region of interest; we're done.
602 return false;
603
604 case RangeOverlap:
605 // This declaration overlaps the region of interest; visit it.
606 break;
607 }
608 }
609 return true;
610}
611
612bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
613 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
614
615 // FIXME: Eventually remove. This part of a hack to support proper
616 // iteration over all Decls contained lexically within an ObjC container.
617 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
618 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
619
620 for ( ; I != E; ++I) {
621 Decl *D = *I;
622 if (D->getLexicalDeclContext() != DC)
623 continue;
624 CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
625
626 // Ignore synthesized ivars here, otherwise if we have something like:
627 // @synthesize prop = _prop;
628 // and '_prop' is not declared, we will encounter a '_prop' ivar before
629 // encountering the 'prop' synthesize declaration and we will think that
630 // we passed the region-of-interest.
631 if (ObjCIvarDecl *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
632 if (ivarD->getSynthesize())
633 continue;
634 }
635
636 // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
637 // declarations is a mismatch with the compiler semantics.
638 if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
639 ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
640 if (!ID->isThisDeclarationADefinition())
641 Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
642
643 } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
644 ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
645 if (!PD->isThisDeclarationADefinition())
646 Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
647 }
648
Ted Kremenek03325582013-02-21 01:29:01 +0000649 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000650 if (!V.hasValue())
651 continue;
652 if (!V.getValue())
653 return false;
654 if (Visit(Cursor, true))
655 return true;
656 }
657 return false;
658}
659
660bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
661 llvm_unreachable("Translation units are visited directly by Visit()");
662}
663
Sergey Kalinichev8f3b1872015-11-15 13:48:32 +0000664bool CursorVisitor::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {
665 if (VisitTemplateParameters(D->getTemplateParameters()))
666 return true;
667
668 return Visit(MakeCXCursor(D->getTemplatedDecl(), TU, RegionOfInterest));
669}
670
Guy Benyei11169dd2012-12-18 14:30:41 +0000671bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
672 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
673 return Visit(TSInfo->getTypeLoc());
674
675 return false;
676}
677
678bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
679 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
680 return Visit(TSInfo->getTypeLoc());
681
682 return false;
683}
684
685bool CursorVisitor::VisitTagDecl(TagDecl *D) {
686 return VisitDeclContext(D);
687}
688
689bool CursorVisitor::VisitClassTemplateSpecializationDecl(
690 ClassTemplateSpecializationDecl *D) {
691 bool ShouldVisitBody = false;
692 switch (D->getSpecializationKind()) {
693 case TSK_Undeclared:
694 case TSK_ImplicitInstantiation:
695 // Nothing to visit
696 return false;
697
698 case TSK_ExplicitInstantiationDeclaration:
699 case TSK_ExplicitInstantiationDefinition:
700 break;
701
702 case TSK_ExplicitSpecialization:
703 ShouldVisitBody = true;
704 break;
705 }
706
707 // Visit the template arguments used in the specialization.
708 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
709 TypeLoc TL = SpecType->getTypeLoc();
David Blaikie6adc78e2013-02-18 22:06:02 +0000710 if (TemplateSpecializationTypeLoc TSTLoc =
711 TL.getAs<TemplateSpecializationTypeLoc>()) {
712 for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
713 if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000714 return true;
715 }
716 }
Alexander Kornienko1a9f1842015-12-28 15:24:08 +0000717
718 return ShouldVisitBody && VisitCXXRecordDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +0000719}
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
Alexander Kornienko1a9f1842015-12-28 15:24:08 +0000943 return ND->isThisDeclarationADefinition() &&
944 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest));
Guy Benyei11169dd2012-12-18 14:30:41 +0000945}
946
947template <typename DeclIt>
948static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
949 SourceManager &SM, SourceLocation EndLoc,
950 SmallVectorImpl<Decl *> &Decls) {
951 DeclIt next = *DI_current;
952 while (++next != DE_current) {
953 Decl *D_next = *next;
954 if (!D_next)
955 break;
956 SourceLocation L = D_next->getLocStart();
957 if (!L.isValid())
958 break;
959 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
960 *DI_current = next;
961 Decls.push_back(D_next);
962 continue;
963 }
964 break;
965 }
966}
967
Guy Benyei11169dd2012-12-18 14:30:41 +0000968bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
969 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
970 // an @implementation can lexically contain Decls that are not properly
971 // nested in the AST. When we identify such cases, we need to retrofit
972 // this nesting here.
973 if (!DI_current && !FileDI_current)
974 return VisitDeclContext(D);
975
976 // Scan the Decls that immediately come after the container
977 // in the current DeclContext. If any fall within the
978 // container's lexical region, stash them into a vector
979 // for later processing.
980 SmallVector<Decl *, 24> DeclsInContainer;
981 SourceLocation EndLoc = D->getSourceRange().getEnd();
982 SourceManager &SM = AU->getSourceManager();
983 if (EndLoc.isValid()) {
984 if (DI_current) {
985 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
986 DeclsInContainer);
987 } else {
988 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
989 DeclsInContainer);
990 }
991 }
992
993 // The common case.
994 if (DeclsInContainer.empty())
995 return VisitDeclContext(D);
996
997 // Get all the Decls in the DeclContext, and sort them with the
998 // additional ones we've collected. Then visit them.
Aaron Ballman629afae2014-03-07 19:56:05 +0000999 for (auto *SubDecl : D->decls()) {
1000 if (!SubDecl || SubDecl->getLexicalDeclContext() != D ||
1001 SubDecl->getLocStart().isInvalid())
Guy Benyei11169dd2012-12-18 14:30:41 +00001002 continue;
Aaron Ballman629afae2014-03-07 19:56:05 +00001003 DeclsInContainer.push_back(SubDecl);
Guy Benyei11169dd2012-12-18 14:30:41 +00001004 }
1005
1006 // Now sort the Decls so that they appear in lexical order.
1007 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
Benjamin Kramerbbdd7642014-03-01 14:48:57 +00001008 [&SM](Decl *A, Decl *B) {
1009 SourceLocation L_A = A->getLocStart();
1010 SourceLocation L_B = B->getLocStart();
1011 assert(L_A.isValid() && L_B.isValid());
1012 return SM.isBeforeInTranslationUnit(L_A, L_B);
1013 });
Guy Benyei11169dd2012-12-18 14:30:41 +00001014
1015 // Now visit the decls.
1016 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
1017 E = DeclsInContainer.end(); I != E; ++I) {
1018 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek03325582013-02-21 01:29:01 +00001019 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00001020 if (!V.hasValue())
1021 continue;
1022 if (!V.getValue())
1023 return false;
1024 if (Visit(Cursor, true))
1025 return true;
1026 }
1027 return false;
1028}
1029
1030bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1031 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1032 TU)))
1033 return true;
1034
Douglas Gregore9d95f12015-07-07 03:57:35 +00001035 if (VisitObjCTypeParamList(ND->getTypeParamList()))
1036 return true;
1037
Guy Benyei11169dd2012-12-18 14:30:41 +00001038 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1039 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1040 E = ND->protocol_end(); I != E; ++I, ++PL)
1041 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1042 return true;
1043
1044 return VisitObjCContainerDecl(ND);
1045}
1046
1047bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1048 if (!PID->isThisDeclarationADefinition())
1049 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1050
1051 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1052 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1053 E = PID->protocol_end(); I != E; ++I, ++PL)
1054 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1055 return true;
1056
1057 return VisitObjCContainerDecl(PID);
1058}
1059
1060bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1061 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1062 return true;
1063
1064 // FIXME: This implements a workaround with @property declarations also being
1065 // installed in the DeclContext for the @interface. Eventually this code
1066 // should be removed.
1067 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1068 if (!CDecl || !CDecl->IsClassExtension())
1069 return false;
1070
1071 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1072 if (!ID)
1073 return false;
1074
1075 IdentifierInfo *PropertyId = PD->getIdentifier();
1076 ObjCPropertyDecl *prevDecl =
Manman Ren5b786402016-01-28 18:49:28 +00001077 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId,
1078 PD->getQueryKind());
Guy Benyei11169dd2012-12-18 14:30:41 +00001079
1080 if (!prevDecl)
1081 return false;
1082
1083 // Visit synthesized methods since they will be skipped when visiting
1084 // the @interface.
1085 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1086 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1087 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1088 return true;
1089
1090 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1091 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1092 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1093 return true;
1094
1095 return false;
1096}
1097
Douglas Gregore9d95f12015-07-07 03:57:35 +00001098bool CursorVisitor::VisitObjCTypeParamList(ObjCTypeParamList *typeParamList) {
1099 if (!typeParamList)
1100 return false;
1101
1102 for (auto *typeParam : *typeParamList) {
1103 // Visit the type parameter.
1104 if (Visit(MakeCXCursor(typeParam, TU, RegionOfInterest)))
1105 return true;
Douglas Gregore9d95f12015-07-07 03:57:35 +00001106 }
1107
1108 return false;
1109}
1110
Guy Benyei11169dd2012-12-18 14:30:41 +00001111bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1112 if (!D->isThisDeclarationADefinition()) {
1113 // Forward declaration is treated like a reference.
1114 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1115 }
1116
Douglas Gregore9d95f12015-07-07 03:57:35 +00001117 // Objective-C type parameters.
1118 if (VisitObjCTypeParamList(D->getTypeParamListAsWritten()))
1119 return true;
1120
Guy Benyei11169dd2012-12-18 14:30:41 +00001121 // Issue callbacks for super class.
1122 if (D->getSuperClass() &&
1123 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1124 D->getSuperClassLoc(),
1125 TU)))
1126 return true;
1127
Douglas Gregore9d95f12015-07-07 03:57:35 +00001128 if (TypeSourceInfo *SuperClassTInfo = D->getSuperClassTInfo())
1129 if (Visit(SuperClassTInfo->getTypeLoc()))
1130 return true;
1131
Guy Benyei11169dd2012-12-18 14:30:41 +00001132 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1133 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1134 E = D->protocol_end(); I != E; ++I, ++PL)
1135 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1136 return true;
1137
1138 return VisitObjCContainerDecl(D);
1139}
1140
1141bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1142 return VisitObjCContainerDecl(D);
1143}
1144
1145bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1146 // 'ID' could be null when dealing with invalid code.
1147 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1148 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1149 return true;
1150
1151 return VisitObjCImplDecl(D);
1152}
1153
1154bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1155#if 0
1156 // Issue callbacks for super class.
1157 // FIXME: No source location information!
1158 if (D->getSuperClass() &&
1159 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1160 D->getSuperClassLoc(),
1161 TU)))
1162 return true;
1163#endif
1164
1165 return VisitObjCImplDecl(D);
1166}
1167
1168bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1169 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1170 if (PD->isIvarNameSpecified())
1171 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1172
1173 return false;
1174}
1175
1176bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1177 return VisitDeclContext(D);
1178}
1179
1180bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1181 // Visit nested-name-specifier.
1182 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1183 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1184 return true;
1185
1186 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1187 D->getTargetNameLoc(), TU));
1188}
1189
1190bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1191 // Visit nested-name-specifier.
1192 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1193 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1194 return true;
1195 }
1196
1197 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1198 return true;
1199
1200 return VisitDeclarationNameInfo(D->getNameInfo());
1201}
1202
1203bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1204 // Visit nested-name-specifier.
1205 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1206 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1207 return true;
1208
1209 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1210 D->getIdentLocation(), TU));
1211}
1212
1213bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1214 // Visit nested-name-specifier.
1215 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1216 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1217 return true;
1218 }
1219
1220 return VisitDeclarationNameInfo(D->getNameInfo());
1221}
1222
1223bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1224 UnresolvedUsingTypenameDecl *D) {
1225 // Visit nested-name-specifier.
1226 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1227 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1228 return true;
1229
1230 return false;
1231}
1232
1233bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1234 switch (Name.getName().getNameKind()) {
1235 case clang::DeclarationName::Identifier:
1236 case clang::DeclarationName::CXXLiteralOperatorName:
1237 case clang::DeclarationName::CXXOperatorName:
1238 case clang::DeclarationName::CXXUsingDirective:
1239 return false;
1240
1241 case clang::DeclarationName::CXXConstructorName:
1242 case clang::DeclarationName::CXXDestructorName:
1243 case clang::DeclarationName::CXXConversionFunctionName:
1244 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1245 return Visit(TSInfo->getTypeLoc());
1246 return false;
1247
1248 case clang::DeclarationName::ObjCZeroArgSelector:
1249 case clang::DeclarationName::ObjCOneArgSelector:
1250 case clang::DeclarationName::ObjCMultiArgSelector:
1251 // FIXME: Per-identifier location info?
1252 return false;
1253 }
1254
1255 llvm_unreachable("Invalid DeclarationName::Kind!");
1256}
1257
1258bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1259 SourceRange Range) {
1260 // FIXME: This whole routine is a hack to work around the lack of proper
1261 // source information in nested-name-specifiers (PR5791). Since we do have
1262 // a beginning source location, we can visit the first component of the
1263 // nested-name-specifier, if it's a single-token component.
1264 if (!NNS)
1265 return false;
1266
1267 // Get the first component in the nested-name-specifier.
1268 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1269 NNS = Prefix;
1270
1271 switch (NNS->getKind()) {
1272 case NestedNameSpecifier::Namespace:
1273 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1274 TU));
1275
1276 case NestedNameSpecifier::NamespaceAlias:
1277 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1278 Range.getBegin(), TU));
1279
1280 case NestedNameSpecifier::TypeSpec: {
1281 // If the type has a form where we know that the beginning of the source
1282 // range matches up with a reference cursor. Visit the appropriate reference
1283 // cursor.
1284 const Type *T = NNS->getAsType();
1285 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1286 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1287 if (const TagType *Tag = dyn_cast<TagType>(T))
1288 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1289 if (const TemplateSpecializationType *TST
1290 = dyn_cast<TemplateSpecializationType>(T))
1291 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1292 break;
1293 }
1294
1295 case NestedNameSpecifier::TypeSpecWithTemplate:
1296 case NestedNameSpecifier::Global:
1297 case NestedNameSpecifier::Identifier:
Nikola Smiljanic67860242014-09-26 00:28:20 +00001298 case NestedNameSpecifier::Super:
Guy Benyei11169dd2012-12-18 14:30:41 +00001299 break;
1300 }
1301
1302 return false;
1303}
1304
1305bool
1306CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1307 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1308 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1309 Qualifiers.push_back(Qualifier);
1310
1311 while (!Qualifiers.empty()) {
1312 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1313 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1314 switch (NNS->getKind()) {
1315 case NestedNameSpecifier::Namespace:
1316 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1317 Q.getLocalBeginLoc(),
1318 TU)))
1319 return true;
1320
1321 break;
1322
1323 case NestedNameSpecifier::NamespaceAlias:
1324 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1325 Q.getLocalBeginLoc(),
1326 TU)))
1327 return true;
1328
1329 break;
1330
1331 case NestedNameSpecifier::TypeSpec:
1332 case NestedNameSpecifier::TypeSpecWithTemplate:
1333 if (Visit(Q.getTypeLoc()))
1334 return true;
1335
1336 break;
1337
1338 case NestedNameSpecifier::Global:
1339 case NestedNameSpecifier::Identifier:
Nikola Smiljanic67860242014-09-26 00:28:20 +00001340 case NestedNameSpecifier::Super:
Guy Benyei11169dd2012-12-18 14:30:41 +00001341 break;
1342 }
1343 }
1344
1345 return false;
1346}
1347
1348bool CursorVisitor::VisitTemplateParameters(
1349 const TemplateParameterList *Params) {
1350 if (!Params)
1351 return false;
1352
1353 for (TemplateParameterList::const_iterator P = Params->begin(),
1354 PEnd = Params->end();
1355 P != PEnd; ++P) {
1356 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1357 return true;
1358 }
1359
1360 return false;
1361}
1362
1363bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1364 switch (Name.getKind()) {
1365 case TemplateName::Template:
1366 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1367
1368 case TemplateName::OverloadedTemplate:
1369 // Visit the overloaded template set.
1370 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1371 return true;
1372
1373 return false;
1374
1375 case TemplateName::DependentTemplate:
1376 // FIXME: Visit nested-name-specifier.
1377 return false;
1378
1379 case TemplateName::QualifiedTemplate:
1380 // FIXME: Visit nested-name-specifier.
1381 return Visit(MakeCursorTemplateRef(
1382 Name.getAsQualifiedTemplateName()->getDecl(),
1383 Loc, TU));
1384
1385 case TemplateName::SubstTemplateTemplateParm:
1386 return Visit(MakeCursorTemplateRef(
1387 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1388 Loc, TU));
1389
1390 case TemplateName::SubstTemplateTemplateParmPack:
1391 return Visit(MakeCursorTemplateRef(
1392 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1393 Loc, TU));
1394 }
1395
1396 llvm_unreachable("Invalid TemplateName::Kind!");
1397}
1398
1399bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1400 switch (TAL.getArgument().getKind()) {
1401 case TemplateArgument::Null:
1402 case TemplateArgument::Integral:
1403 case TemplateArgument::Pack:
1404 return false;
1405
1406 case TemplateArgument::Type:
1407 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1408 return Visit(TSInfo->getTypeLoc());
1409 return false;
1410
1411 case TemplateArgument::Declaration:
1412 if (Expr *E = TAL.getSourceDeclExpression())
1413 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1414 return false;
1415
1416 case TemplateArgument::NullPtr:
1417 if (Expr *E = TAL.getSourceNullPtrExpression())
1418 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1419 return false;
1420
1421 case TemplateArgument::Expression:
1422 if (Expr *E = TAL.getSourceExpression())
1423 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1424 return false;
1425
1426 case TemplateArgument::Template:
1427 case TemplateArgument::TemplateExpansion:
1428 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1429 return true;
1430
1431 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1432 TAL.getTemplateNameLoc());
1433 }
1434
1435 llvm_unreachable("Invalid TemplateArgument::Kind!");
1436}
1437
1438bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1439 return VisitDeclContext(D);
1440}
1441
1442bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1443 return Visit(TL.getUnqualifiedLoc());
1444}
1445
1446bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1447 ASTContext &Context = AU->getASTContext();
1448
1449 // Some builtin types (such as Objective-C's "id", "sel", and
1450 // "Class") have associated declarations. Create cursors for those.
1451 QualType VisitType;
1452 switch (TL.getTypePtr()->getKind()) {
1453
1454 case BuiltinType::Void:
1455 case BuiltinType::NullPtr:
1456 case BuiltinType::Dependent:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001457 case BuiltinType::OCLImage1d:
1458 case BuiltinType::OCLImage1dArray:
1459 case BuiltinType::OCLImage1dBuffer:
1460 case BuiltinType::OCLImage2d:
1461 case BuiltinType::OCLImage2dArray:
Alexey Bader9c8453f2015-09-15 11:18:52 +00001462 case BuiltinType::OCLImage2dDepth:
1463 case BuiltinType::OCLImage2dArrayDepth:
1464 case BuiltinType::OCLImage2dMSAA:
1465 case BuiltinType::OCLImage2dArrayMSAA:
1466 case BuiltinType::OCLImage2dMSAADepth:
1467 case BuiltinType::OCLImage2dArrayMSAADepth:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001468 case BuiltinType::OCLImage3d:
NAKAMURA Takumi288c42e2013-02-07 12:47:42 +00001469 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +00001470 case BuiltinType::OCLEvent:
Alexey Bader9c8453f2015-09-15 11:18:52 +00001471 case BuiltinType::OCLClkEvent:
1472 case BuiltinType::OCLQueue:
1473 case BuiltinType::OCLNDRange:
1474 case BuiltinType::OCLReserveID:
Guy Benyei11169dd2012-12-18 14:30:41 +00001475#define BUILTIN_TYPE(Id, SingletonId)
1476#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1477#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1478#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1479#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1480#include "clang/AST/BuiltinTypes.def"
1481 break;
1482
1483 case BuiltinType::ObjCId:
1484 VisitType = Context.getObjCIdType();
1485 break;
1486
1487 case BuiltinType::ObjCClass:
1488 VisitType = Context.getObjCClassType();
1489 break;
1490
1491 case BuiltinType::ObjCSel:
1492 VisitType = Context.getObjCSelType();
1493 break;
1494 }
1495
1496 if (!VisitType.isNull()) {
1497 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1498 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1499 TU));
1500 }
1501
1502 return false;
1503}
1504
1505bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1506 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1507}
1508
1509bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1510 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1511}
1512
1513bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1514 if (TL.isDefinition())
1515 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1516
1517 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1518}
1519
1520bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1521 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1522}
1523
1524bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
Hans Wennborg59dbe862015-09-29 20:56:43 +00001525 return Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +00001526}
1527
1528bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1529 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1530 return true;
1531
Douglas Gregore9d95f12015-07-07 03:57:35 +00001532 for (unsigned I = 0, N = TL.getNumTypeArgs(); I != N; ++I) {
1533 if (Visit(TL.getTypeArgTInfo(I)->getTypeLoc()))
1534 return true;
1535 }
1536
Guy Benyei11169dd2012-12-18 14:30:41 +00001537 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1538 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1539 TU)))
1540 return true;
1541 }
1542
1543 return false;
1544}
1545
1546bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1547 return Visit(TL.getPointeeLoc());
1548}
1549
1550bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1551 return Visit(TL.getInnerLoc());
1552}
1553
1554bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1555 return Visit(TL.getPointeeLoc());
1556}
1557
1558bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1559 return Visit(TL.getPointeeLoc());
1560}
1561
1562bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1563 return Visit(TL.getPointeeLoc());
1564}
1565
1566bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1567 return Visit(TL.getPointeeLoc());
1568}
1569
1570bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1571 return Visit(TL.getPointeeLoc());
1572}
1573
1574bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1575 return Visit(TL.getModifiedLoc());
1576}
1577
1578bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1579 bool SkipResultType) {
Alp Toker42a16a62014-01-25 23:51:36 +00001580 if (!SkipResultType && Visit(TL.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001581 return true;
1582
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00001583 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1584 if (Decl *D = TL.getParam(I))
Guy Benyei11169dd2012-12-18 14:30:41 +00001585 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1586 return true;
1587
1588 return false;
1589}
1590
1591bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1592 if (Visit(TL.getElementLoc()))
1593 return true;
1594
1595 if (Expr *Size = TL.getSizeExpr())
1596 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1597
1598 return false;
1599}
1600
Reid Kleckner8a365022013-06-24 17:51:48 +00001601bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1602 return Visit(TL.getOriginalLoc());
1603}
1604
Reid Kleckner0503a872013-12-05 01:23:43 +00001605bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1606 return Visit(TL.getOriginalLoc());
1607}
1608
Guy Benyei11169dd2012-12-18 14:30:41 +00001609bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1610 TemplateSpecializationTypeLoc TL) {
1611 // Visit the template name.
1612 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1613 TL.getTemplateNameLoc()))
1614 return true;
1615
1616 // Visit the template arguments.
1617 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1618 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1619 return true;
1620
1621 return false;
1622}
1623
1624bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1625 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1626}
1627
1628bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1629 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1630 return Visit(TSInfo->getTypeLoc());
1631
1632 return false;
1633}
1634
1635bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1636 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1637 return Visit(TSInfo->getTypeLoc());
1638
1639 return false;
1640}
1641
1642bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
Hans Wennborg59dbe862015-09-29 20:56:43 +00001643 return VisitNestedNameSpecifierLoc(TL.getQualifierLoc());
Guy Benyei11169dd2012-12-18 14:30:41 +00001644}
1645
1646bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1647 DependentTemplateSpecializationTypeLoc TL) {
1648 // Visit the nested-name-specifier, if there is one.
1649 if (TL.getQualifierLoc() &&
1650 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1651 return true;
1652
1653 // Visit the template arguments.
1654 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1655 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1656 return true;
1657
1658 return false;
1659}
1660
1661bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1662 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1663 return true;
1664
1665 return Visit(TL.getNamedTypeLoc());
1666}
1667
1668bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1669 return Visit(TL.getPatternLoc());
1670}
1671
1672bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1673 if (Expr *E = TL.getUnderlyingExpr())
1674 return Visit(MakeCXCursor(E, StmtParent, TU));
1675
1676 return false;
1677}
1678
1679bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1680 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1681}
1682
1683bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1684 return Visit(TL.getValueLoc());
1685}
1686
Xiuli Pan9c14e282016-01-09 12:53:17 +00001687bool CursorVisitor::VisitPipeTypeLoc(PipeTypeLoc TL) {
1688 return Visit(TL.getValueLoc());
1689}
1690
Guy Benyei11169dd2012-12-18 14:30:41 +00001691#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1692bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1693 return Visit##PARENT##Loc(TL); \
1694}
1695
1696DEFAULT_TYPELOC_IMPL(Complex, Type)
1697DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1698DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1699DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1700DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1701DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1702DEFAULT_TYPELOC_IMPL(Vector, Type)
1703DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1704DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1705DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1706DEFAULT_TYPELOC_IMPL(Record, TagType)
1707DEFAULT_TYPELOC_IMPL(Enum, TagType)
1708DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1709DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1710DEFAULT_TYPELOC_IMPL(Auto, Type)
1711
1712bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1713 // Visit the nested-name-specifier, if present.
1714 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1715 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1716 return true;
1717
1718 if (D->isCompleteDefinition()) {
Aaron Ballman574705e2014-03-13 15:41:46 +00001719 for (const auto &I : D->bases()) {
1720 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001721 return true;
1722 }
1723 }
1724
1725 return VisitTagDecl(D);
1726}
1727
1728bool CursorVisitor::VisitAttributes(Decl *D) {
Aaron Ballmanb97112e2014-03-08 22:19:01 +00001729 for (const auto *I : D->attrs())
1730 if (Visit(MakeCXCursor(I, D, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001731 return true;
1732
1733 return false;
1734}
1735
1736//===----------------------------------------------------------------------===//
1737// Data-recursive visitor methods.
1738//===----------------------------------------------------------------------===//
1739
1740namespace {
1741#define DEF_JOB(NAME, DATA, KIND)\
1742class NAME : public VisitorJob {\
1743public:\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001744 NAME(const DATA *d, CXCursor parent) : \
1745 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei11169dd2012-12-18 14:30:41 +00001746 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001747 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei11169dd2012-12-18 14:30:41 +00001748};
1749
1750DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1751DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1752DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1753DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
Guy Benyei11169dd2012-12-18 14:30:41 +00001754DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1755DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1756DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1757#undef DEF_JOB
1758
James Y Knight04ec5bf2015-12-24 02:59:37 +00001759class ExplicitTemplateArgsVisit : public VisitorJob {
1760public:
1761 ExplicitTemplateArgsVisit(const TemplateArgumentLoc *Begin,
1762 const TemplateArgumentLoc *End, CXCursor parent)
1763 : VisitorJob(parent, VisitorJob::ExplicitTemplateArgsVisitKind, Begin,
1764 End) {}
1765 static bool classof(const VisitorJob *VJ) {
1766 return VJ->getKind() == ExplicitTemplateArgsVisitKind;
1767 }
1768 const TemplateArgumentLoc *begin() const {
1769 return static_cast<const TemplateArgumentLoc *>(data[0]);
1770 }
1771 const TemplateArgumentLoc *end() {
1772 return static_cast<const TemplateArgumentLoc *>(data[1]);
1773 }
1774};
Guy Benyei11169dd2012-12-18 14:30:41 +00001775class DeclVisit : public VisitorJob {
1776public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001777 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei11169dd2012-12-18 14:30:41 +00001778 VisitorJob(parent, VisitorJob::DeclVisitKind,
Craig Topper69186e72014-06-08 08:38:04 +00001779 D, isFirst ? (void*) 1 : (void*) nullptr) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001780 static bool classof(const VisitorJob *VJ) {
1781 return VJ->getKind() == DeclVisitKind;
1782 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001783 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Dmitri Gribenkoe5423a72015-03-23 19:23:50 +00001784 bool isFirst() const { return data[1] != nullptr; }
Guy Benyei11169dd2012-12-18 14:30:41 +00001785};
1786class TypeLocVisit : public VisitorJob {
1787public:
1788 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1789 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1790 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1791
1792 static bool classof(const VisitorJob *VJ) {
1793 return VJ->getKind() == TypeLocVisitKind;
1794 }
1795
1796 TypeLoc get() const {
1797 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001798 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001799 }
1800};
1801
1802class LabelRefVisit : public VisitorJob {
1803public:
1804 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1805 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1806 labelLoc.getPtrEncoding()) {}
1807
1808 static bool classof(const VisitorJob *VJ) {
1809 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1810 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001811 const LabelDecl *get() const {
1812 return static_cast<const LabelDecl *>(data[0]);
1813 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001814 SourceLocation getLoc() const {
1815 return SourceLocation::getFromPtrEncoding(data[1]); }
1816};
1817
1818class NestedNameSpecifierLocVisit : public VisitorJob {
1819public:
1820 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1821 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1822 Qualifier.getNestedNameSpecifier(),
1823 Qualifier.getOpaqueData()) { }
1824
1825 static bool classof(const VisitorJob *VJ) {
1826 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1827 }
1828
1829 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001830 return NestedNameSpecifierLoc(
1831 const_cast<NestedNameSpecifier *>(
1832 static_cast<const NestedNameSpecifier *>(data[0])),
1833 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001834 }
1835};
1836
1837class DeclarationNameInfoVisit : public VisitorJob {
1838public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001839 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001840 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001841 static bool classof(const VisitorJob *VJ) {
1842 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1843 }
1844 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001845 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001846 switch (S->getStmtClass()) {
1847 default:
1848 llvm_unreachable("Unhandled Stmt");
1849 case clang::Stmt::MSDependentExistsStmtClass:
1850 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1851 case Stmt::CXXDependentScopeMemberExprClass:
1852 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1853 case Stmt::DependentScopeDeclRefExprClass:
1854 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001855 case Stmt::OMPCriticalDirectiveClass:
1856 return cast<OMPCriticalDirective>(S)->getDirectiveName();
Guy Benyei11169dd2012-12-18 14:30:41 +00001857 }
1858 }
1859};
1860class MemberRefVisit : public VisitorJob {
1861public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001862 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei11169dd2012-12-18 14:30:41 +00001863 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1864 L.getPtrEncoding()) {}
1865 static bool classof(const VisitorJob *VJ) {
1866 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1867 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001868 const FieldDecl *get() const {
1869 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001870 }
1871 SourceLocation getLoc() const {
1872 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1873 }
1874};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001875class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001876 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001877 VisitorWorkList &WL;
1878 CXCursor Parent;
1879public:
1880 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1881 : WL(wl), Parent(parent) {}
1882
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001883 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1884 void VisitBlockExpr(const BlockExpr *B);
1885 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1886 void VisitCompoundStmt(const CompoundStmt *S);
1887 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1888 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1889 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1890 void VisitCXXNewExpr(const CXXNewExpr *E);
1891 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1892 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1893 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1894 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1895 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1896 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1897 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1898 void VisitCXXCatchStmt(const CXXCatchStmt *S);
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00001899 void VisitCXXForRangeStmt(const CXXForRangeStmt *S);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001900 void VisitDeclRefExpr(const DeclRefExpr *D);
1901 void VisitDeclStmt(const DeclStmt *S);
1902 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1903 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1904 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1905 void VisitForStmt(const ForStmt *FS);
1906 void VisitGotoStmt(const GotoStmt *GS);
1907 void VisitIfStmt(const IfStmt *If);
1908 void VisitInitListExpr(const InitListExpr *IE);
1909 void VisitMemberExpr(const MemberExpr *M);
1910 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1911 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1912 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1913 void VisitOverloadExpr(const OverloadExpr *E);
1914 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1915 void VisitStmt(const Stmt *S);
1916 void VisitSwitchStmt(const SwitchStmt *S);
1917 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001918 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1919 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1920 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1921 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1922 void VisitVAArgExpr(const VAArgExpr *E);
1923 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1924 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1925 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1926 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001927 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
Alexander Musman3aaab662014-08-19 11:27:13 +00001928 void VisitOMPLoopDirective(const OMPLoopDirective *D);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001929 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00001930 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00001931 void VisitOMPForDirective(const OMPForDirective *D);
Alexander Musmanf82886e2014-09-18 05:12:34 +00001932 void VisitOMPForSimdDirective(const OMPForSimdDirective *D);
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00001933 void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
Alexey Bataev1e0498a2014-06-26 08:21:58 +00001934 void VisitOMPSectionDirective(const OMPSectionDirective *D);
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00001935 void VisitOMPSingleDirective(const OMPSingleDirective *D);
Alexander Musman80c22892014-07-17 08:54:58 +00001936 void VisitOMPMasterDirective(const OMPMasterDirective *D);
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001937 void VisitOMPCriticalDirective(const OMPCriticalDirective *D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00001938 void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
Alexander Musmane4e893b2014-09-23 09:33:00 +00001939 void VisitOMPParallelForSimdDirective(const OMPParallelForSimdDirective *D);
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00001940 void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective *D);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00001941 void VisitOMPTaskDirective(const OMPTaskDirective *D);
Alexey Bataev68446b72014-07-18 07:47:19 +00001942 void VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D);
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00001943 void VisitOMPBarrierDirective(const OMPBarrierDirective *D);
Alexey Bataev2df347a2014-07-18 10:17:07 +00001944 void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00001945 void VisitOMPTaskgroupDirective(const OMPTaskgroupDirective *D);
Alexey Bataev6d4ed052015-07-01 06:57:41 +00001946 void
1947 VisitOMPCancellationPointDirective(const OMPCancellationPointDirective *D);
Alexey Bataev80909872015-07-02 11:25:17 +00001948 void VisitOMPCancelDirective(const OMPCancelDirective *D);
Alexey Bataev6125da92014-07-21 11:26:11 +00001949 void VisitOMPFlushDirective(const OMPFlushDirective *D);
Alexey Bataev9fb6e642014-07-22 06:45:04 +00001950 void VisitOMPOrderedDirective(const OMPOrderedDirective *D);
Alexey Bataev0162e452014-07-22 10:10:35 +00001951 void VisitOMPAtomicDirective(const OMPAtomicDirective *D);
Alexey Bataev0bd520b2014-09-19 08:19:49 +00001952 void VisitOMPTargetDirective(const OMPTargetDirective *D);
Michael Wong65f367f2015-07-21 13:44:28 +00001953 void VisitOMPTargetDataDirective(const OMPTargetDataDirective *D);
Samuel Antaodf67fc42016-01-19 19:15:56 +00001954 void VisitOMPTargetEnterDataDirective(const OMPTargetEnterDataDirective *D);
Samuel Antao72590762016-01-19 20:04:50 +00001955 void VisitOMPTargetExitDataDirective(const OMPTargetExitDataDirective *D);
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00001956 void VisitOMPTargetParallelDirective(const OMPTargetParallelDirective *D);
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00001957 void
1958 VisitOMPTargetParallelForDirective(const OMPTargetParallelForDirective *D);
Alexey Bataev13314bf2014-10-09 04:18:56 +00001959 void VisitOMPTeamsDirective(const OMPTeamsDirective *D);
Alexey Bataev49f6e782015-12-01 04:18:41 +00001960 void VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *D);
Alexey Bataev0a6ed842015-12-03 09:40:15 +00001961 void VisitOMPTaskLoopSimdDirective(const OMPTaskLoopSimdDirective *D);
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00001962 void VisitOMPDistributeDirective(const OMPDistributeDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001963
Guy Benyei11169dd2012-12-18 14:30:41 +00001964private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001965 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001966 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
James Y Knight04ec5bf2015-12-24 02:59:37 +00001967 void AddExplicitTemplateArgs(const TemplateArgumentLoc *A,
1968 unsigned NumTemplateArgs);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001969 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1970 void AddStmt(const Stmt *S);
1971 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001972 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001973 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001974 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001975};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00001976} // end anonyous namespace
Guy Benyei11169dd2012-12-18 14:30:41 +00001977
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001978void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001979 // 'S' should always be non-null, since it comes from the
1980 // statement we are visiting.
1981 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1982}
1983
1984void
1985EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1986 if (Qualifier)
1987 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1988}
1989
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001990void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001991 if (S)
1992 WL.push_back(StmtVisit(S, Parent));
1993}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001994void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001995 if (D)
1996 WL.push_back(DeclVisit(D, Parent, isFirst));
1997}
James Y Knight04ec5bf2015-12-24 02:59:37 +00001998void EnqueueVisitor::AddExplicitTemplateArgs(const TemplateArgumentLoc *A,
1999 unsigned NumTemplateArgs) {
2000 WL.push_back(ExplicitTemplateArgsVisit(A, A + NumTemplateArgs, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00002001}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002002void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002003 if (D)
2004 WL.push_back(MemberRefVisit(D, L, Parent));
2005}
2006void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
2007 if (TI)
2008 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
2009 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002010void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002011 unsigned size = WL.size();
Benjamin Kramer642f1732015-07-02 21:03:14 +00002012 for (const Stmt *SubStmt : S->children()) {
2013 AddStmt(SubStmt);
Guy Benyei11169dd2012-12-18 14:30:41 +00002014 }
2015 if (size == WL.size())
2016 return;
2017 // Now reverse the entries we just added. This will match the DFS
2018 // ordering performed by the worklist.
2019 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2020 std::reverse(I, E);
2021}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002022namespace {
2023class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
2024 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00002025 /// \brief Process clauses with list of variables.
2026 template <typename T>
2027 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002028public:
2029 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
2030#define OPENMP_CLAUSE(Name, Class) \
2031 void Visit##Class(const Class *C);
2032#include "clang/Basic/OpenMPKinds.def"
Alexey Bataev3392d762016-02-16 11:18:12 +00002033 void VisitOMPClauseWithPreInit(const OMPClauseWithPreInit *C);
Alexey Bataev005248a2016-02-25 05:25:57 +00002034 void VisitOMPClauseWithPostUpdate(const OMPClauseWithPostUpdate *C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002035};
2036
Alexey Bataev3392d762016-02-16 11:18:12 +00002037void OMPClauseEnqueue::VisitOMPClauseWithPreInit(
2038 const OMPClauseWithPreInit *C) {
2039 Visitor->AddStmt(C->getPreInitStmt());
2040}
2041
Alexey Bataev005248a2016-02-25 05:25:57 +00002042void OMPClauseEnqueue::VisitOMPClauseWithPostUpdate(
2043 const OMPClauseWithPostUpdate *C) {
2044 Visitor->AddStmt(C->getPostUpdateExpr());
2045}
2046
Alexey Bataevaadd52e2014-02-13 05:29:23 +00002047void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
2048 Visitor->AddStmt(C->getCondition());
2049}
2050
Alexey Bataev3778b602014-07-17 07:32:53 +00002051void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
2052 Visitor->AddStmt(C->getCondition());
2053}
2054
Alexey Bataev568a8332014-03-06 06:15:19 +00002055void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
2056 Visitor->AddStmt(C->getNumThreads());
2057}
2058
Alexey Bataev62c87d22014-03-21 04:51:18 +00002059void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
2060 Visitor->AddStmt(C->getSafelen());
2061}
2062
Alexey Bataev66b15b52015-08-21 11:14:16 +00002063void OMPClauseEnqueue::VisitOMPSimdlenClause(const OMPSimdlenClause *C) {
2064 Visitor->AddStmt(C->getSimdlen());
2065}
2066
Alexander Musman8bd31e62014-05-27 15:12:19 +00002067void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
2068 Visitor->AddStmt(C->getNumForLoops());
2069}
2070
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002071void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00002072
Alexey Bataevbcbadb62014-05-06 06:04:14 +00002073void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
2074
Alexey Bataev56dafe82014-06-20 07:16:17 +00002075void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
Alexey Bataev3392d762016-02-16 11:18:12 +00002076 VisitOMPClauseWithPreInit(C);
Alexey Bataev56dafe82014-06-20 07:16:17 +00002077 Visitor->AddStmt(C->getChunkSize());
2078}
2079
Alexey Bataev10e775f2015-07-30 11:36:16 +00002080void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *C) {
2081 Visitor->AddStmt(C->getNumForLoops());
2082}
Alexey Bataev142e1fc2014-06-20 09:44:06 +00002083
Alexey Bataev236070f2014-06-20 11:19:47 +00002084void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
2085
Alexey Bataev7aea99a2014-07-17 12:19:31 +00002086void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
2087
Alexey Bataev74ba3a52014-07-17 12:47:03 +00002088void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
2089
Alexey Bataevf98b00c2014-07-23 02:27:21 +00002090void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}
2091
Alexey Bataevdea47612014-07-23 07:46:59 +00002092void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {}
2093
Alexey Bataev67a4f222014-07-23 10:25:33 +00002094void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {}
2095
Alexey Bataev459dec02014-07-24 06:46:57 +00002096void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}
2097
Alexey Bataev82bad8b2014-07-24 08:55:34 +00002098void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
2099
Alexey Bataev346265e2015-09-25 10:37:12 +00002100void OMPClauseEnqueue::VisitOMPThreadsClause(const OMPThreadsClause *) {}
2101
Alexey Bataevd14d1e62015-09-28 06:39:35 +00002102void OMPClauseEnqueue::VisitOMPSIMDClause(const OMPSIMDClause *) {}
2103
Alexey Bataevb825de12015-12-07 10:51:44 +00002104void OMPClauseEnqueue::VisitOMPNogroupClause(const OMPNogroupClause *) {}
2105
Michael Wonge710d542015-08-07 16:16:36 +00002106void OMPClauseEnqueue::VisitOMPDeviceClause(const OMPDeviceClause *C) {
2107 Visitor->AddStmt(C->getDevice());
2108}
2109
Kelvin Li099bb8c2015-11-24 20:50:12 +00002110void OMPClauseEnqueue::VisitOMPNumTeamsClause(const OMPNumTeamsClause *C) {
2111 Visitor->AddStmt(C->getNumTeams());
2112}
2113
Kelvin Lia15fb1a2015-11-27 18:47:36 +00002114void OMPClauseEnqueue::VisitOMPThreadLimitClause(const OMPThreadLimitClause *C) {
2115 Visitor->AddStmt(C->getThreadLimit());
2116}
2117
Alexey Bataeva0569352015-12-01 10:17:31 +00002118void OMPClauseEnqueue::VisitOMPPriorityClause(const OMPPriorityClause *C) {
2119 Visitor->AddStmt(C->getPriority());
2120}
2121
Alexey Bataev1fd4aed2015-12-07 12:52:51 +00002122void OMPClauseEnqueue::VisitOMPGrainsizeClause(const OMPGrainsizeClause *C) {
2123 Visitor->AddStmt(C->getGrainsize());
2124}
2125
Alexey Bataev382967a2015-12-08 12:06:20 +00002126void OMPClauseEnqueue::VisitOMPNumTasksClause(const OMPNumTasksClause *C) {
2127 Visitor->AddStmt(C->getNumTasks());
2128}
2129
Alexey Bataev28c75412015-12-15 08:19:24 +00002130void OMPClauseEnqueue::VisitOMPHintClause(const OMPHintClause *C) {
2131 Visitor->AddStmt(C->getHint());
2132}
2133
Alexey Bataev756c1962013-09-24 03:17:45 +00002134template<typename T>
2135void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Alexey Bataev03b340a2014-10-21 03:16:40 +00002136 for (const auto *I : Node->varlists()) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00002137 Visitor->AddStmt(I);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002138 }
Alexey Bataev756c1962013-09-24 03:17:45 +00002139}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002140
2141void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002142 VisitOMPClauseList(C);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002143 for (const auto *E : C->private_copies()) {
2144 Visitor->AddStmt(E);
2145 }
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002146}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002147void OMPClauseEnqueue::VisitOMPFirstprivateClause(
2148 const OMPFirstprivateClause *C) {
2149 VisitOMPClauseList(C);
Alexey Bataev417089f2016-02-17 13:19:37 +00002150 VisitOMPClauseWithPreInit(C);
2151 for (const auto *E : C->private_copies()) {
2152 Visitor->AddStmt(E);
2153 }
2154 for (const auto *E : C->inits()) {
2155 Visitor->AddStmt(E);
2156 }
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002157}
Alexander Musman1bb328c2014-06-04 13:06:39 +00002158void OMPClauseEnqueue::VisitOMPLastprivateClause(
2159 const OMPLastprivateClause *C) {
2160 VisitOMPClauseList(C);
Alexey Bataev005248a2016-02-25 05:25:57 +00002161 VisitOMPClauseWithPreInit(C);
2162 VisitOMPClauseWithPostUpdate(C);
Alexey Bataev38e89532015-04-16 04:54:05 +00002163 for (auto *E : C->private_copies()) {
2164 Visitor->AddStmt(E);
2165 }
2166 for (auto *E : C->source_exprs()) {
2167 Visitor->AddStmt(E);
2168 }
2169 for (auto *E : C->destination_exprs()) {
2170 Visitor->AddStmt(E);
2171 }
2172 for (auto *E : C->assignment_ops()) {
2173 Visitor->AddStmt(E);
2174 }
Alexander Musman1bb328c2014-06-04 13:06:39 +00002175}
Alexey Bataev758e55e2013-09-06 18:03:48 +00002176void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002177 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00002178}
Alexey Bataevc5e02582014-06-16 07:08:35 +00002179void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
2180 VisitOMPClauseList(C);
Alexey Bataevf24e7b12015-10-08 09:10:53 +00002181 for (auto *E : C->privates()) {
2182 Visitor->AddStmt(E);
2183 }
Alexey Bataev794ba0d2015-04-10 10:43:45 +00002184 for (auto *E : C->lhs_exprs()) {
2185 Visitor->AddStmt(E);
2186 }
2187 for (auto *E : C->rhs_exprs()) {
2188 Visitor->AddStmt(E);
2189 }
2190 for (auto *E : C->reduction_ops()) {
2191 Visitor->AddStmt(E);
2192 }
Alexey Bataevc5e02582014-06-16 07:08:35 +00002193}
Alexander Musman8dba6642014-04-22 13:09:42 +00002194void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2195 VisitOMPClauseList(C);
Alexey Bataevbd9fec12015-08-18 06:47:21 +00002196 for (const auto *E : C->privates()) {
2197 Visitor->AddStmt(E);
2198 }
Alexander Musman3276a272015-03-21 10:12:56 +00002199 for (const auto *E : C->inits()) {
2200 Visitor->AddStmt(E);
2201 }
2202 for (const auto *E : C->updates()) {
2203 Visitor->AddStmt(E);
2204 }
2205 for (const auto *E : C->finals()) {
2206 Visitor->AddStmt(E);
2207 }
Alexander Musman8dba6642014-04-22 13:09:42 +00002208 Visitor->AddStmt(C->getStep());
Alexander Musman3276a272015-03-21 10:12:56 +00002209 Visitor->AddStmt(C->getCalcStep());
Alexander Musman8dba6642014-04-22 13:09:42 +00002210}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002211void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2212 VisitOMPClauseList(C);
2213 Visitor->AddStmt(C->getAlignment());
2214}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002215void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2216 VisitOMPClauseList(C);
Alexey Bataevf56f98c2015-04-16 05:39:01 +00002217 for (auto *E : C->source_exprs()) {
2218 Visitor->AddStmt(E);
2219 }
2220 for (auto *E : C->destination_exprs()) {
2221 Visitor->AddStmt(E);
2222 }
2223 for (auto *E : C->assignment_ops()) {
2224 Visitor->AddStmt(E);
2225 }
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002226}
Alexey Bataevbae9a792014-06-27 10:37:06 +00002227void
2228OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
2229 VisitOMPClauseList(C);
Alexey Bataeva63048e2015-03-23 06:18:07 +00002230 for (auto *E : C->source_exprs()) {
2231 Visitor->AddStmt(E);
2232 }
2233 for (auto *E : C->destination_exprs()) {
2234 Visitor->AddStmt(E);
2235 }
2236 for (auto *E : C->assignment_ops()) {
2237 Visitor->AddStmt(E);
2238 }
Alexey Bataevbae9a792014-06-27 10:37:06 +00002239}
Alexey Bataev6125da92014-07-21 11:26:11 +00002240void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2241 VisitOMPClauseList(C);
2242}
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +00002243void OMPClauseEnqueue::VisitOMPDependClause(const OMPDependClause *C) {
2244 VisitOMPClauseList(C);
2245}
Kelvin Li0bff7af2015-11-23 05:32:03 +00002246void OMPClauseEnqueue::VisitOMPMapClause(const OMPMapClause *C) {
2247 VisitOMPClauseList(C);
2248}
Carlo Bertollib4adf552016-01-15 18:50:31 +00002249void OMPClauseEnqueue::VisitOMPDistScheduleClause(
2250 const OMPDistScheduleClause *C) {
Alexey Bataev3392d762016-02-16 11:18:12 +00002251 VisitOMPClauseWithPreInit(C);
Carlo Bertollib4adf552016-01-15 18:50:31 +00002252 Visitor->AddStmt(C->getChunkSize());
Carlo Bertollib4adf552016-01-15 18:50:31 +00002253}
Alexey Bataev3392d762016-02-16 11:18:12 +00002254void OMPClauseEnqueue::VisitOMPDefaultmapClause(
2255 const OMPDefaultmapClause * /*C*/) {}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002256}
Alexey Bataev756c1962013-09-24 03:17:45 +00002257
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002258void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2259 unsigned size = WL.size();
2260 OMPClauseEnqueue Visitor(this);
2261 Visitor.Visit(S);
2262 if (size == WL.size())
2263 return;
2264 // Now reverse the entries we just added. This will match the DFS
2265 // ordering performed by the worklist.
2266 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2267 std::reverse(I, E);
2268}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002269void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002270 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2271}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002272void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002273 AddDecl(B->getBlockDecl());
2274}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002275void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002276 EnqueueChildren(E);
2277 AddTypeLoc(E->getTypeSourceInfo());
2278}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002279void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
Pete Cooper57d3f142015-07-30 17:22:52 +00002280 for (auto &I : llvm::reverse(S->body()))
2281 AddStmt(I);
Guy Benyei11169dd2012-12-18 14:30:41 +00002282}
2283void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002284VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002285 AddStmt(S->getSubStmt());
2286 AddDeclarationNameInfo(S);
2287 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2288 AddNestedNameSpecifierLoc(QualifierLoc);
2289}
2290
2291void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002292VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002293 if (E->hasExplicitTemplateArgs())
2294 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002295 AddDeclarationNameInfo(E);
2296 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2297 AddNestedNameSpecifierLoc(QualifierLoc);
2298 if (!E->isImplicitAccess())
2299 AddStmt(E->getBase());
2300}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002301void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002302 // Enqueue the initializer , if any.
2303 AddStmt(E->getInitializer());
2304 // Enqueue the array size, if any.
2305 AddStmt(E->getArraySize());
2306 // Enqueue the allocated type.
2307 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2308 // Enqueue the placement arguments.
2309 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2310 AddStmt(E->getPlacementArg(I-1));
2311}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002312void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002313 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2314 AddStmt(CE->getArg(I-1));
2315 AddStmt(CE->getCallee());
2316 AddStmt(CE->getArg(0));
2317}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002318void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2319 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002320 // Visit the name of the type being destroyed.
2321 AddTypeLoc(E->getDestroyedTypeInfo());
2322 // Visit the scope type that looks disturbingly like the nested-name-specifier
2323 // but isn't.
2324 AddTypeLoc(E->getScopeTypeInfo());
2325 // Visit the nested-name-specifier.
2326 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2327 AddNestedNameSpecifierLoc(QualifierLoc);
2328 // Visit base expression.
2329 AddStmt(E->getBase());
2330}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002331void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2332 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002333 AddTypeLoc(E->getTypeSourceInfo());
2334}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002335void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2336 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002337 EnqueueChildren(E);
2338 AddTypeLoc(E->getTypeSourceInfo());
2339}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002340void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002341 EnqueueChildren(E);
2342 if (E->isTypeOperand())
2343 AddTypeLoc(E->getTypeOperandSourceInfo());
2344}
2345
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002346void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2347 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002348 EnqueueChildren(E);
2349 AddTypeLoc(E->getTypeSourceInfo());
2350}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002351void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002352 EnqueueChildren(E);
2353 if (E->isTypeOperand())
2354 AddTypeLoc(E->getTypeOperandSourceInfo());
2355}
2356
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002357void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002358 EnqueueChildren(S);
2359 AddDecl(S->getExceptionDecl());
2360}
2361
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002362void EnqueueVisitor::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002363 AddStmt(S->getBody());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002364 AddStmt(S->getRangeInit());
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002365 AddDecl(S->getLoopVariable());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002366}
2367
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002368void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002369 if (DR->hasExplicitTemplateArgs())
2370 AddExplicitTemplateArgs(DR->getTemplateArgs(), DR->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002371 WL.push_back(DeclRefExprParts(DR, Parent));
2372}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002373void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2374 const DependentScopeDeclRefExpr *E) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002375 if (E->hasExplicitTemplateArgs())
2376 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002377 AddDeclarationNameInfo(E);
2378 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2379}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002380void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002381 unsigned size = WL.size();
2382 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002383 for (const auto *D : S->decls()) {
2384 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002385 isFirst = false;
2386 }
2387 if (size == WL.size())
2388 return;
2389 // Now reverse the entries we just added. This will match the DFS
2390 // ordering performed by the worklist.
2391 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2392 std::reverse(I, E);
2393}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002394void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002395 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002396 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002397 D = E->designators_rbegin(), DEnd = E->designators_rend();
2398 D != DEnd; ++D) {
2399 if (D->isFieldDesignator()) {
2400 if (FieldDecl *Field = D->getField())
2401 AddMemberRef(Field, D->getFieldLoc());
2402 continue;
2403 }
2404 if (D->isArrayDesignator()) {
2405 AddStmt(E->getArrayIndex(*D));
2406 continue;
2407 }
2408 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2409 AddStmt(E->getArrayRangeEnd(*D));
2410 AddStmt(E->getArrayRangeStart(*D));
2411 }
2412}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002413void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002414 EnqueueChildren(E);
2415 AddTypeLoc(E->getTypeInfoAsWritten());
2416}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002417void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002418 AddStmt(FS->getBody());
2419 AddStmt(FS->getInc());
2420 AddStmt(FS->getCond());
2421 AddDecl(FS->getConditionVariable());
2422 AddStmt(FS->getInit());
2423}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002424void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002425 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2426}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002427void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002428 AddStmt(If->getElse());
2429 AddStmt(If->getThen());
2430 AddStmt(If->getCond());
2431 AddDecl(If->getConditionVariable());
2432}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002433void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002434 // We care about the syntactic form of the initializer list, only.
2435 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2436 IE = Syntactic;
2437 EnqueueChildren(IE);
2438}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002439void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002440 WL.push_back(MemberExprParts(M, Parent));
2441
2442 // If the base of the member access expression is an implicit 'this', don't
2443 // visit it.
2444 // FIXME: If we ever want to show these implicit accesses, this will be
2445 // unfortunate. However, clang_getCursor() relies on this behavior.
Argyrios Kyrtzidis58d0e7a2015-03-13 04:40:07 +00002446 if (M->isImplicitAccess())
2447 return;
2448
2449 // Ignore base anonymous struct/union fields, otherwise they will shadow the
2450 // real field that that we are interested in.
2451 if (auto *SubME = dyn_cast<MemberExpr>(M->getBase())) {
2452 if (auto *FD = dyn_cast_or_null<FieldDecl>(SubME->getMemberDecl())) {
2453 if (FD->isAnonymousStructOrUnion()) {
2454 AddStmt(SubME->getBase());
2455 return;
2456 }
2457 }
2458 }
2459
2460 AddStmt(M->getBase());
Guy Benyei11169dd2012-12-18 14:30:41 +00002461}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002462void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002463 AddTypeLoc(E->getEncodedTypeSourceInfo());
2464}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002465void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002466 EnqueueChildren(M);
2467 AddTypeLoc(M->getClassReceiverTypeInfo());
2468}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002469void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002470 // Visit the components of the offsetof expression.
2471 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002472 const OffsetOfNode &Node = E->getComponent(I-1);
2473 switch (Node.getKind()) {
2474 case OffsetOfNode::Array:
2475 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2476 break;
2477 case OffsetOfNode::Field:
2478 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2479 break;
2480 case OffsetOfNode::Identifier:
2481 case OffsetOfNode::Base:
2482 continue;
2483 }
2484 }
2485 // Visit the type into which we're computing the offset.
2486 AddTypeLoc(E->getTypeSourceInfo());
2487}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002488void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002489 if (E->hasExplicitTemplateArgs())
2490 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002491 WL.push_back(OverloadExprParts(E, Parent));
2492}
2493void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002494 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002495 EnqueueChildren(E);
2496 if (E->isArgumentType())
2497 AddTypeLoc(E->getArgumentTypeInfo());
2498}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002499void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002500 EnqueueChildren(S);
2501}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002502void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002503 AddStmt(S->getBody());
2504 AddStmt(S->getCond());
2505 AddDecl(S->getConditionVariable());
2506}
2507
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002508void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002509 AddStmt(W->getBody());
2510 AddStmt(W->getCond());
2511 AddDecl(W->getConditionVariable());
2512}
2513
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002514void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002515 for (unsigned I = E->getNumArgs(); I > 0; --I)
2516 AddTypeLoc(E->getArg(I-1));
2517}
2518
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002519void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002520 AddTypeLoc(E->getQueriedTypeSourceInfo());
2521}
2522
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002523void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002524 EnqueueChildren(E);
2525}
2526
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002527void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002528 VisitOverloadExpr(U);
2529 if (!U->isImplicitAccess())
2530 AddStmt(U->getBase());
2531}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002532void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002533 AddStmt(E->getSubExpr());
2534 AddTypeLoc(E->getWrittenTypeInfo());
2535}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002536void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002537 WL.push_back(SizeOfPackExprParts(E, Parent));
2538}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002539void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002540 // If the opaque value has a source expression, just transparently
2541 // visit that. This is useful for (e.g.) pseudo-object expressions.
2542 if (Expr *SourceExpr = E->getSourceExpr())
2543 return Visit(SourceExpr);
2544}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002545void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002546 AddStmt(E->getBody());
2547 WL.push_back(LambdaExprParts(E, Parent));
2548}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002549void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002550 // Treat the expression like its syntactic form.
2551 Visit(E->getSyntacticForm());
2552}
2553
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002554void EnqueueVisitor::VisitOMPExecutableDirective(
2555 const OMPExecutableDirective *D) {
2556 EnqueueChildren(D);
2557 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2558 E = D->clauses().end();
2559 I != E; ++I)
2560 EnqueueChildren(*I);
2561}
2562
Alexander Musman3aaab662014-08-19 11:27:13 +00002563void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
2564 VisitOMPExecutableDirective(D);
2565}
2566
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002567void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2568 VisitOMPExecutableDirective(D);
2569}
2570
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002571void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002572 VisitOMPLoopDirective(D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002573}
2574
Alexey Bataevf29276e2014-06-18 04:14:57 +00002575void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002576 VisitOMPLoopDirective(D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002577}
2578
Alexander Musmanf82886e2014-09-18 05:12:34 +00002579void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
2580 VisitOMPLoopDirective(D);
2581}
2582
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002583void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2584 VisitOMPExecutableDirective(D);
2585}
2586
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002587void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2588 VisitOMPExecutableDirective(D);
2589}
2590
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002591void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2592 VisitOMPExecutableDirective(D);
2593}
2594
Alexander Musman80c22892014-07-17 08:54:58 +00002595void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2596 VisitOMPExecutableDirective(D);
2597}
2598
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002599void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2600 VisitOMPExecutableDirective(D);
2601 AddDeclarationNameInfo(D);
2602}
2603
Alexey Bataev4acb8592014-07-07 13:01:15 +00002604void
2605EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002606 VisitOMPLoopDirective(D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002607}
2608
Alexander Musmane4e893b2014-09-23 09:33:00 +00002609void EnqueueVisitor::VisitOMPParallelForSimdDirective(
2610 const OMPParallelForSimdDirective *D) {
2611 VisitOMPLoopDirective(D);
2612}
2613
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002614void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2615 const OMPParallelSectionsDirective *D) {
2616 VisitOMPExecutableDirective(D);
2617}
2618
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002619void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2620 VisitOMPExecutableDirective(D);
2621}
2622
Alexey Bataev68446b72014-07-18 07:47:19 +00002623void
2624EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2625 VisitOMPExecutableDirective(D);
2626}
2627
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002628void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2629 VisitOMPExecutableDirective(D);
2630}
2631
Alexey Bataev2df347a2014-07-18 10:17:07 +00002632void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2633 VisitOMPExecutableDirective(D);
2634}
2635
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002636void EnqueueVisitor::VisitOMPTaskgroupDirective(
2637 const OMPTaskgroupDirective *D) {
2638 VisitOMPExecutableDirective(D);
2639}
2640
Alexey Bataev6125da92014-07-21 11:26:11 +00002641void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2642 VisitOMPExecutableDirective(D);
2643}
2644
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002645void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2646 VisitOMPExecutableDirective(D);
2647}
2648
Alexey Bataev0162e452014-07-22 10:10:35 +00002649void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2650 VisitOMPExecutableDirective(D);
2651}
2652
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002653void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
2654 VisitOMPExecutableDirective(D);
2655}
2656
Michael Wong65f367f2015-07-21 13:44:28 +00002657void EnqueueVisitor::VisitOMPTargetDataDirective(const
2658 OMPTargetDataDirective *D) {
2659 VisitOMPExecutableDirective(D);
2660}
2661
Samuel Antaodf67fc42016-01-19 19:15:56 +00002662void EnqueueVisitor::VisitOMPTargetEnterDataDirective(
2663 const OMPTargetEnterDataDirective *D) {
2664 VisitOMPExecutableDirective(D);
2665}
2666
Samuel Antao72590762016-01-19 20:04:50 +00002667void EnqueueVisitor::VisitOMPTargetExitDataDirective(
2668 const OMPTargetExitDataDirective *D) {
2669 VisitOMPExecutableDirective(D);
2670}
2671
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00002672void EnqueueVisitor::VisitOMPTargetParallelDirective(
2673 const OMPTargetParallelDirective *D) {
2674 VisitOMPExecutableDirective(D);
2675}
2676
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00002677void EnqueueVisitor::VisitOMPTargetParallelForDirective(
2678 const OMPTargetParallelForDirective *D) {
2679 VisitOMPLoopDirective(D);
2680}
2681
Alexey Bataev13314bf2014-10-09 04:18:56 +00002682void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {
2683 VisitOMPExecutableDirective(D);
2684}
2685
Alexey Bataev6d4ed052015-07-01 06:57:41 +00002686void EnqueueVisitor::VisitOMPCancellationPointDirective(
2687 const OMPCancellationPointDirective *D) {
2688 VisitOMPExecutableDirective(D);
2689}
2690
Alexey Bataev80909872015-07-02 11:25:17 +00002691void EnqueueVisitor::VisitOMPCancelDirective(const OMPCancelDirective *D) {
2692 VisitOMPExecutableDirective(D);
2693}
2694
Alexey Bataev49f6e782015-12-01 04:18:41 +00002695void EnqueueVisitor::VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *D) {
2696 VisitOMPLoopDirective(D);
2697}
2698
Alexey Bataev0a6ed842015-12-03 09:40:15 +00002699void EnqueueVisitor::VisitOMPTaskLoopSimdDirective(
2700 const OMPTaskLoopSimdDirective *D) {
2701 VisitOMPLoopDirective(D);
2702}
2703
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00002704void EnqueueVisitor::VisitOMPDistributeDirective(
2705 const OMPDistributeDirective *D) {
2706 VisitOMPLoopDirective(D);
2707}
2708
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002709void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002710 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2711}
2712
2713bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2714 if (RegionOfInterest.isValid()) {
2715 SourceRange Range = getRawCursorExtent(C);
2716 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2717 return false;
2718 }
2719 return true;
2720}
2721
2722bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2723 while (!WL.empty()) {
2724 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002725 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002726
2727 // Set the Parent field, then back to its old value once we're done.
2728 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2729
2730 switch (LI.getKind()) {
2731 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002732 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002733 if (!D)
2734 continue;
2735
2736 // For now, perform default visitation for Decls.
2737 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2738 cast<DeclVisit>(&LI)->isFirst())))
2739 return true;
2740
2741 continue;
2742 }
2743 case VisitorJob::ExplicitTemplateArgsVisitKind: {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002744 for (const TemplateArgumentLoc &Arg :
2745 *cast<ExplicitTemplateArgsVisit>(&LI)) {
2746 if (VisitTemplateArgumentLoc(Arg))
Guy Benyei11169dd2012-12-18 14:30:41 +00002747 return true;
2748 }
2749 continue;
2750 }
2751 case VisitorJob::TypeLocVisitKind: {
2752 // Perform default visitation for TypeLocs.
2753 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2754 return true;
2755 continue;
2756 }
2757 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002758 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002759 if (LabelStmt *stmt = LS->getStmt()) {
2760 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2761 TU))) {
2762 return true;
2763 }
2764 }
2765 continue;
2766 }
2767
2768 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2769 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2770 if (VisitNestedNameSpecifierLoc(V->get()))
2771 return true;
2772 continue;
2773 }
2774
2775 case VisitorJob::DeclarationNameInfoVisitKind: {
2776 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2777 ->get()))
2778 return true;
2779 continue;
2780 }
2781 case VisitorJob::MemberRefVisitKind: {
2782 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2783 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2784 return true;
2785 continue;
2786 }
2787 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002788 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002789 if (!S)
2790 continue;
2791
2792 // Update the current cursor.
2793 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2794 if (!IsInRegionOfInterest(Cursor))
2795 continue;
2796 switch (Visitor(Cursor, Parent, ClientData)) {
2797 case CXChildVisit_Break: return true;
2798 case CXChildVisit_Continue: break;
2799 case CXChildVisit_Recurse:
2800 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002801 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002802 EnqueueWorkList(WL, S);
2803 break;
2804 }
2805 continue;
2806 }
2807 case VisitorJob::MemberExprPartsKind: {
2808 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002809 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002810
2811 // Visit the nested-name-specifier
2812 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2813 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2814 return true;
2815
2816 // Visit the declaration name.
2817 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2818 return true;
2819
2820 // Visit the explicitly-specified template arguments, if any.
2821 if (M->hasExplicitTemplateArgs()) {
2822 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2823 *ArgEnd = Arg + M->getNumTemplateArgs();
2824 Arg != ArgEnd; ++Arg) {
2825 if (VisitTemplateArgumentLoc(*Arg))
2826 return true;
2827 }
2828 }
2829 continue;
2830 }
2831 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002832 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002833 // Visit nested-name-specifier, if present.
2834 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2835 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2836 return true;
2837 // Visit declaration name.
2838 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2839 return true;
2840 continue;
2841 }
2842 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002843 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002844 // Visit the nested-name-specifier.
2845 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2846 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2847 return true;
2848 // Visit the declaration name.
2849 if (VisitDeclarationNameInfo(O->getNameInfo()))
2850 return true;
2851 // Visit the overloaded declaration reference.
2852 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2853 return true;
2854 continue;
2855 }
2856 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002857 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002858 NamedDecl *Pack = E->getPack();
2859 if (isa<TemplateTypeParmDecl>(Pack)) {
2860 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2861 E->getPackLoc(), TU)))
2862 return true;
2863
2864 continue;
2865 }
2866
2867 if (isa<TemplateTemplateParmDecl>(Pack)) {
2868 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2869 E->getPackLoc(), TU)))
2870 return true;
2871
2872 continue;
2873 }
2874
2875 // Non-type template parameter packs and function parameter packs are
2876 // treated like DeclRefExpr cursors.
2877 continue;
2878 }
2879
2880 case VisitorJob::LambdaExprPartsKind: {
2881 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002882 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002883 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2884 CEnd = E->explicit_capture_end();
2885 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002886 // FIXME: Lambda init-captures.
2887 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002888 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002889
Guy Benyei11169dd2012-12-18 14:30:41 +00002890 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2891 C->getLocation(),
2892 TU)))
2893 return true;
2894 }
2895
2896 // Visit parameters and return type, if present.
2897 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2898 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2899 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2900 // Visit the whole type.
2901 if (Visit(TL))
2902 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002903 } else if (FunctionProtoTypeLoc Proto =
2904 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002905 if (E->hasExplicitParameters()) {
2906 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002907 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2908 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002909 return true;
2910 } else {
2911 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002912 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002913 return true;
2914 }
2915 }
2916 }
2917 break;
2918 }
2919
2920 case VisitorJob::PostChildrenVisitKind:
2921 if (PostChildrenVisitor(Parent, ClientData))
2922 return true;
2923 break;
2924 }
2925 }
2926 return false;
2927}
2928
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002929bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002930 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002931 if (!WorkListFreeList.empty()) {
2932 WL = WorkListFreeList.back();
2933 WL->clear();
2934 WorkListFreeList.pop_back();
2935 }
2936 else {
2937 WL = new VisitorWorkList();
2938 WorkListCache.push_back(WL);
2939 }
2940 EnqueueWorkList(*WL, S);
2941 bool result = RunVisitorWorkList(*WL);
2942 WorkListFreeList.push_back(WL);
2943 return result;
2944}
2945
2946namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002947typedef SmallVector<SourceRange, 4> RefNamePieces;
James Y Knight04ec5bf2015-12-24 02:59:37 +00002948RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2949 const DeclarationNameInfo &NI, SourceRange QLoc,
2950 const SourceRange *TemplateArgsLoc = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002951 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2952 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2953 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2954
2955 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2956
2957 RefNamePieces Pieces;
2958
2959 if (WantQualifier && QLoc.isValid())
2960 Pieces.push_back(QLoc);
2961
2962 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2963 Pieces.push_back(NI.getLoc());
James Y Knight04ec5bf2015-12-24 02:59:37 +00002964
2965 if (WantTemplateArgs && TemplateArgsLoc && TemplateArgsLoc->isValid())
2966 Pieces.push_back(*TemplateArgsLoc);
2967
Guy Benyei11169dd2012-12-18 14:30:41 +00002968 if (Kind == DeclarationName::CXXOperatorName) {
2969 Pieces.push_back(SourceLocation::getFromRawEncoding(
2970 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2971 Pieces.push_back(SourceLocation::getFromRawEncoding(
2972 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2973 }
2974
2975 if (WantSinglePiece) {
2976 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2977 Pieces.clear();
2978 Pieces.push_back(R);
2979 }
2980
2981 return Pieces;
2982}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002983}
Guy Benyei11169dd2012-12-18 14:30:41 +00002984
2985//===----------------------------------------------------------------------===//
2986// Misc. API hooks.
2987//===----------------------------------------------------------------------===//
2988
Chad Rosier05c71aa2013-03-27 18:28:23 +00002989static void fatal_error_handler(void *user_data, const std::string& reason,
2990 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002991 // Write the result out to stderr avoiding errs() because raw_ostreams can
2992 // call report_fatal_error.
2993 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2994 ::abort();
2995}
2996
Chandler Carruth66660742014-06-27 16:37:27 +00002997namespace {
2998struct RegisterFatalErrorHandler {
2999 RegisterFatalErrorHandler() {
3000 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
3001 }
3002};
3003}
3004
3005static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
3006
Guy Benyei11169dd2012-12-18 14:30:41 +00003007extern "C" {
3008CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
3009 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003010 // We use crash recovery to make some of our APIs more reliable, implicitly
3011 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00003012 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
3013 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00003014
Chandler Carruth66660742014-06-27 16:37:27 +00003015 // Look through the managed static to trigger construction of the managed
3016 // static which registers our fatal error handler. This ensures it is only
3017 // registered once.
3018 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00003019
Adrian Prantlbc068582015-07-08 01:00:30 +00003020 // Initialize targets for clang module support.
3021 llvm::InitializeAllTargets();
3022 llvm::InitializeAllTargetMCs();
3023 llvm::InitializeAllAsmPrinters();
3024 llvm::InitializeAllAsmParsers();
3025
Adrian Prantlfb2398d2015-07-17 01:19:54 +00003026 CIndexer *CIdxr = new CIndexer();
3027
Guy Benyei11169dd2012-12-18 14:30:41 +00003028 if (excludeDeclarationsFromPCH)
3029 CIdxr->setOnlyLocalDecls();
3030 if (displayDiagnostics)
3031 CIdxr->setDisplayDiagnostics();
3032
3033 if (getenv("LIBCLANG_BGPRIO_INDEX"))
3034 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
3035 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
3036 if (getenv("LIBCLANG_BGPRIO_EDIT"))
3037 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
3038 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
3039
3040 return CIdxr;
3041}
3042
3043void clang_disposeIndex(CXIndex CIdx) {
3044 if (CIdx)
3045 delete static_cast<CIndexer *>(CIdx);
3046}
3047
3048void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
3049 if (CIdx)
3050 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
3051}
3052
3053unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
3054 if (CIdx)
3055 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
3056 return 0;
3057}
3058
3059void clang_toggleCrashRecovery(unsigned isEnabled) {
3060 if (isEnabled)
3061 llvm::CrashRecoveryContext::Enable();
3062 else
3063 llvm::CrashRecoveryContext::Disable();
3064}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003065
Guy Benyei11169dd2012-12-18 14:30:41 +00003066CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
3067 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003068 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003069 enum CXErrorCode Result =
3070 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00003071 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003072 assert((TU && Result == CXError_Success) ||
3073 (!TU && Result != CXError_Success));
3074 return TU;
3075}
3076
3077enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
3078 const char *ast_filename,
3079 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003080 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00003081 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003082
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003083 if (!CIdx || !ast_filename || !out_TU)
3084 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00003085
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00003086 LOG_FUNC_SECTION {
3087 *Log << ast_filename;
3088 }
3089
Guy Benyei11169dd2012-12-18 14:30:41 +00003090 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3091 FileSystemOptions FileSystemOpts;
3092
Justin Bognerd512c1e2014-10-15 00:33:06 +00003093 IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
3094 CompilerInstance::createDiagnostics(new DiagnosticOptions());
David Blaikie6f7382d2014-08-10 19:08:04 +00003095 std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
Adrian Prantlfb2398d2015-07-17 01:19:54 +00003096 ast_filename, CXXIdx->getPCHContainerOperations()->getRawReader(), Diags,
Adrian Prantl6b21ab22015-08-27 19:46:20 +00003097 FileSystemOpts, /*UseDebugInfo=*/false,
3098 CXXIdx->getOnlyLocalDecls(), None,
David Blaikie6f7382d2014-08-10 19:08:04 +00003099 /*CaptureDiagnostics=*/true,
3100 /*AllowPCHWithCompilerErrors=*/true,
3101 /*UserFilesAreVolatile=*/true);
3102 *out_TU = MakeCXTranslationUnit(CXXIdx, AU.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003103 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003104}
3105
3106unsigned clang_defaultEditingTranslationUnitOptions() {
3107 return CXTranslationUnit_PrecompiledPreamble |
3108 CXTranslationUnit_CacheCompletionResults;
3109}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003110
Guy Benyei11169dd2012-12-18 14:30:41 +00003111CXTranslationUnit
3112clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
3113 const char *source_filename,
3114 int num_command_line_args,
3115 const char * const *command_line_args,
3116 unsigned num_unsaved_files,
3117 struct CXUnsavedFile *unsaved_files) {
3118 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
3119 return clang_parseTranslationUnit(CIdx, source_filename,
3120 command_line_args, num_command_line_args,
3121 unsaved_files, num_unsaved_files,
3122 Options);
3123}
3124
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003125static CXErrorCode
3126clang_parseTranslationUnit_Impl(CXIndex CIdx, const char *source_filename,
3127 const char *const *command_line_args,
3128 int num_command_line_args,
3129 ArrayRef<CXUnsavedFile> unsaved_files,
3130 unsigned options, CXTranslationUnit *out_TU) {
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003131 // Set up the initial return values.
3132 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00003133 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003134
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003135 // Check arguments.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003136 if (!CIdx || !out_TU)
3137 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003138
Guy Benyei11169dd2012-12-18 14:30:41 +00003139 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3140
3141 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3142 setThreadBackgroundPriority();
3143
3144 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
Benjamin Kramer5c248d82015-12-15 09:30:31 +00003145 bool CreatePreambleOnFirstParse =
3146 options & CXTranslationUnit_CreatePreambleOnFirstParse;
Guy Benyei11169dd2012-12-18 14:30:41 +00003147 // FIXME: Add a flag for modules.
3148 TranslationUnitKind TUKind
3149 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00003150 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00003151 = options & CXTranslationUnit_CacheCompletionResults;
3152 bool IncludeBriefCommentsInCodeCompletion
3153 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
3154 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
3155 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
3156
3157 // Configure the diagnostics.
3158 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00003159 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00003160
3161 // Recover resources if we crash before exiting this function.
3162 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
3163 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00003164 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00003165
Ahmed Charlesb8984322014-03-07 20:03:18 +00003166 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3167 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003168
3169 // Recover resources if we crash before exiting this function.
3170 llvm::CrashRecoveryContextCleanupRegistrar<
3171 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3172
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003173 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003174 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003175 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003176 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003177 }
3178
Ahmed Charlesb8984322014-03-07 20:03:18 +00003179 std::unique_ptr<std::vector<const char *>> Args(
3180 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003181
3182 // Recover resources if we crash before exiting this method.
3183 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
3184 ArgsCleanup(Args.get());
3185
3186 // Since the Clang C library is primarily used by batch tools dealing with
3187 // (often very broken) source code, where spell-checking can have a
3188 // significant negative impact on performance (particularly when
3189 // precompiled headers are involved), we disable it by default.
3190 // Only do this if we haven't found a spell-checking-related argument.
3191 bool FoundSpellCheckingArgument = false;
3192 for (int I = 0; I != num_command_line_args; ++I) {
3193 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
3194 strcmp(command_line_args[I], "-fspell-checking") == 0) {
3195 FoundSpellCheckingArgument = true;
3196 break;
3197 }
3198 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003199 Args->insert(Args->end(), command_line_args,
3200 command_line_args + num_command_line_args);
3201
Benjamin Kramerc02670e2015-11-18 16:14:27 +00003202 if (!FoundSpellCheckingArgument)
3203 Args->insert(Args->begin() + 1, "-fno-spell-checking");
3204
Guy Benyei11169dd2012-12-18 14:30:41 +00003205 // The 'source_filename' argument is optional. If the caller does not
3206 // specify it then it is assumed that the source file is specified
3207 // in the actual argument list.
3208 // Put the source file after command_line_args otherwise if '-x' flag is
3209 // present it will be unused.
3210 if (source_filename)
3211 Args->push_back(source_filename);
3212
3213 // Do we need the detailed preprocessing record?
3214 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
3215 Args->push_back("-Xclang");
3216 Args->push_back("-detailed-preprocessing-record");
3217 }
3218
3219 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00003220 std::unique_ptr<ASTUnit> ErrUnit;
Benjamin Kramer5c248d82015-12-15 09:30:31 +00003221 // Unless the user specified that they want the preamble on the first parse
3222 // set it up to be created on the first reparse. This makes the first parse
3223 // faster, trading for a slower (first) reparse.
3224 unsigned PrecompilePreambleAfterNParses =
3225 !PrecompilePreamble ? 0 : 2 - CreatePreambleOnFirstParse;
Ahmed Charlesb8984322014-03-07 20:03:18 +00003226 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003227 Args->data(), Args->data() + Args->size(),
3228 CXXIdx->getPCHContainerOperations(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00003229 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
3230 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
Benjamin Kramer5c248d82015-12-15 09:30:31 +00003231 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreambleAfterNParses,
3232 TUKind, CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
Ahmed Charlesb8984322014-03-07 20:03:18 +00003233 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
Argyrios Kyrtzidisa3e2ff12015-11-20 03:36:21 +00003234 /*UserFilesAreVolatile=*/true, ForSerialization,
3235 CXXIdx->getPCHContainerOperations()->getRawReader().getFormat(),
3236 &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00003237
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003238 // Early failures in LoadFromCommandLine may return with ErrUnit unset.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003239 if (!Unit && !ErrUnit)
3240 return CXError_ASTReadError;
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003241
Guy Benyei11169dd2012-12-18 14:30:41 +00003242 if (NumErrors != Diags->getClient()->getNumErrors()) {
3243 // Make sure to check that 'Unit' is non-NULL.
3244 if (CXXIdx->getDisplayDiagnostics())
3245 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
3246 }
3247
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003248 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get()))
3249 return CXError_ASTReadError;
3250
3251 *out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
3252 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003253}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003254
3255CXTranslationUnit
3256clang_parseTranslationUnit(CXIndex CIdx,
3257 const char *source_filename,
3258 const char *const *command_line_args,
3259 int num_command_line_args,
3260 struct CXUnsavedFile *unsaved_files,
3261 unsigned num_unsaved_files,
3262 unsigned options) {
3263 CXTranslationUnit TU;
3264 enum CXErrorCode Result = clang_parseTranslationUnit2(
3265 CIdx, source_filename, command_line_args, num_command_line_args,
3266 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00003267 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003268 assert((TU && Result == CXError_Success) ||
3269 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003270 return TU;
3271}
3272
3273enum CXErrorCode clang_parseTranslationUnit2(
Benjamin Kramerc02670e2015-11-18 16:14:27 +00003274 CXIndex CIdx, const char *source_filename,
3275 const char *const *command_line_args, int num_command_line_args,
3276 struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
3277 unsigned options, CXTranslationUnit *out_TU) {
3278 SmallVector<const char *, 4> Args;
3279 Args.push_back("clang");
3280 Args.append(command_line_args, command_line_args + num_command_line_args);
3281 return clang_parseTranslationUnit2FullArgv(
3282 CIdx, source_filename, Args.data(), Args.size(), unsaved_files,
3283 num_unsaved_files, options, out_TU);
3284}
3285
3286enum CXErrorCode clang_parseTranslationUnit2FullArgv(
3287 CXIndex CIdx, const char *source_filename,
3288 const char *const *command_line_args, int num_command_line_args,
3289 struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
3290 unsigned options, CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003291 LOG_FUNC_SECTION {
3292 *Log << source_filename << ": ";
3293 for (int i = 0; i != num_command_line_args; ++i)
3294 *Log << command_line_args[i] << " ";
3295 }
3296
Alp Toker9d85b182014-07-07 01:23:14 +00003297 if (num_unsaved_files && !unsaved_files)
3298 return CXError_InvalidArguments;
3299
Alp Toker5c532982014-07-07 22:42:03 +00003300 CXErrorCode result = CXError_Failure;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003301 auto ParseTranslationUnitImpl = [=, &result] {
3302 result = clang_parseTranslationUnit_Impl(
3303 CIdx, source_filename, command_line_args, num_command_line_args,
3304 llvm::makeArrayRef(unsaved_files, num_unsaved_files), options, out_TU);
3305 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003306 llvm::CrashRecoveryContext CRC;
3307
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003308 if (!RunSafely(CRC, ParseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003309 fprintf(stderr, "libclang: crash detected during parsing: {\n");
3310 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3311 fprintf(stderr, " 'command_line_args' : [");
3312 for (int i = 0; i != num_command_line_args; ++i) {
3313 if (i)
3314 fprintf(stderr, ", ");
3315 fprintf(stderr, "'%s'", command_line_args[i]);
3316 }
3317 fprintf(stderr, "],\n");
3318 fprintf(stderr, " 'unsaved_files' : [");
3319 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3320 if (i)
3321 fprintf(stderr, ", ");
3322 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3323 unsaved_files[i].Length);
3324 }
3325 fprintf(stderr, "],\n");
3326 fprintf(stderr, " 'options' : %d,\n", options);
3327 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003328
3329 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003330 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003331 if (CXTranslationUnit *TU = out_TU)
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003332 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003333 }
Alp Toker5c532982014-07-07 22:42:03 +00003334
3335 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003336}
3337
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003338CXString clang_Type_getObjCEncoding(CXType CT) {
3339 CXTranslationUnit tu = static_cast<CXTranslationUnit>(CT.data[1]);
3340 ASTContext &Ctx = getASTUnit(tu)->getASTContext();
3341 std::string encoding;
3342 Ctx.getObjCEncodingForType(QualType::getFromOpaquePtr(CT.data[0]),
3343 encoding);
3344
3345 return cxstring::createDup(encoding);
3346}
3347
3348static const IdentifierInfo *getMacroIdentifier(CXCursor C) {
3349 if (C.kind == CXCursor_MacroDefinition) {
3350 if (const MacroDefinitionRecord *MDR = getCursorMacroDefinition(C))
3351 return MDR->getName();
3352 } else if (C.kind == CXCursor_MacroExpansion) {
3353 MacroExpansionCursor ME = getCursorMacroExpansion(C);
3354 return ME.getName();
3355 }
3356 return nullptr;
3357}
3358
3359unsigned clang_Cursor_isMacroFunctionLike(CXCursor C) {
3360 const IdentifierInfo *II = getMacroIdentifier(C);
3361 if (!II) {
3362 return false;
3363 }
3364 ASTUnit *ASTU = getCursorASTUnit(C);
3365 Preprocessor &PP = ASTU->getPreprocessor();
3366 if (const MacroInfo *MI = PP.getMacroInfo(II))
3367 return MI->isFunctionLike();
3368 return false;
3369}
3370
3371unsigned clang_Cursor_isMacroBuiltin(CXCursor C) {
3372 const IdentifierInfo *II = getMacroIdentifier(C);
3373 if (!II) {
3374 return false;
3375 }
3376 ASTUnit *ASTU = getCursorASTUnit(C);
3377 Preprocessor &PP = ASTU->getPreprocessor();
3378 if (const MacroInfo *MI = PP.getMacroInfo(II))
3379 return MI->isBuiltinMacro();
3380 return false;
3381}
3382
3383unsigned clang_Cursor_isFunctionInlined(CXCursor C) {
3384 const Decl *D = getCursorDecl(C);
3385 const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D);
3386 if (!FD) {
3387 return false;
3388 }
3389 return FD->isInlined();
3390}
3391
3392static StringLiteral* getCFSTR_value(CallExpr *callExpr) {
3393 if (callExpr->getNumArgs() != 1) {
3394 return nullptr;
3395 }
3396
3397 StringLiteral *S = nullptr;
3398 auto *arg = callExpr->getArg(0);
3399 if (arg->getStmtClass() == Stmt::ImplicitCastExprClass) {
3400 ImplicitCastExpr *I = static_cast<ImplicitCastExpr *>(arg);
3401 auto *subExpr = I->getSubExprAsWritten();
3402
3403 if(subExpr->getStmtClass() != Stmt::StringLiteralClass){
3404 return nullptr;
3405 }
3406
3407 S = static_cast<StringLiteral *>(I->getSubExprAsWritten());
3408 } else if (arg->getStmtClass() == Stmt::StringLiteralClass) {
3409 S = static_cast<StringLiteral *>(callExpr->getArg(0));
3410 } else {
3411 return nullptr;
3412 }
3413 return S;
3414}
3415
3416typedef struct {
3417 CXEvalResultKind EvalType;
3418 union {
3419 int intVal;
3420 double floatVal;
3421 char *stringVal;
3422 } EvalData;
3423} ExprEvalResult;
3424
3425void clang_EvalResult_dispose(CXEvalResult E) {
3426 ExprEvalResult *ER = (ExprEvalResult *)E;
3427 if (ER) {
3428 CXEvalResultKind evalType = ER->EvalType;
3429
3430 if (evalType != CXEval_UnExposed && evalType != CXEval_Float &&
3431 evalType != CXEval_Int && ER->EvalData.stringVal) {
3432 free((void *) ER->EvalData.stringVal);
3433 }
3434 free((void *)ER);
3435 }
3436}
3437
3438CXEvalResultKind clang_EvalResult_getKind(CXEvalResult E) {
3439 if (!E) {
3440 return CXEval_UnExposed;
3441 }
3442 return ((ExprEvalResult *)E)->EvalType;
3443}
3444
3445int clang_EvalResult_getAsInt(CXEvalResult E) {
3446 if (!E) {
3447 return 0;
3448 }
3449 return ((ExprEvalResult *)E)->EvalData.intVal;
3450}
3451
3452double clang_EvalResult_getAsDouble(CXEvalResult E) {
3453 if (!E) {
3454 return 0;
3455 }
3456 return ((ExprEvalResult *)E)->EvalData.floatVal;
3457}
3458
3459const char* clang_EvalResult_getAsStr(CXEvalResult E) {
3460 if (!E) {
3461 return nullptr;
3462 }
3463 return ((ExprEvalResult *)E)->EvalData.stringVal;
3464}
3465
3466static const ExprEvalResult* evaluateExpr(Expr *expr, CXCursor C) {
3467 Expr::EvalResult ER;
3468 ASTContext &ctx = getCursorContext(C);
3469 if (!expr) {
3470 return nullptr;
3471 }
3472 expr = expr->IgnoreParens();
3473 bool res = expr->EvaluateAsRValue(ER, ctx);
3474 QualType rettype;
3475 CallExpr *callExpr;
3476 ExprEvalResult *result = (ExprEvalResult *) malloc(sizeof(ExprEvalResult));
3477 if (!result) {
3478 return nullptr;
3479 }
3480 result->EvalType = CXEval_UnExposed;
3481
3482 if (res) {
3483
3484 if (ER.Val.isInt()) {
3485 result->EvalType = CXEval_Int;
3486 result->EvalData.intVal = ER.Val.getInt().getExtValue();
3487 return result;
3488 } else if (ER.Val.isFloat()) {
3489
3490 llvm::SmallVector<char, 100> Buffer;
3491 ER.Val.getFloat().toString(Buffer);
3492 std::string floatStr(Buffer.data(), Buffer.size());
3493 result->EvalType = CXEval_Float;
3494 bool ignored;
3495 llvm::APFloat apFloat = ER.Val.getFloat();
3496 apFloat.convert(llvm::APFloat::IEEEdouble,
3497 llvm::APFloat::rmNearestTiesToEven, &ignored);
3498 result->EvalData.floatVal = apFloat.convertToDouble();
3499 return result;
3500
3501 } else if (expr->getStmtClass() == Stmt::ImplicitCastExprClass) {
3502
3503 const ImplicitCastExpr *I = dyn_cast<ImplicitCastExpr>(expr);
3504 auto *subExpr = I->getSubExprAsWritten();
3505 if (subExpr->getStmtClass() == Stmt::StringLiteralClass ||
3506 subExpr->getStmtClass() == Stmt::ObjCStringLiteralClass) {
3507
3508 const StringLiteral *StrE = nullptr;
3509 const ObjCStringLiteral *ObjCExpr;
3510 ObjCExpr = dyn_cast<ObjCStringLiteral>(subExpr);
3511
3512 if (ObjCExpr) {
3513 StrE = ObjCExpr->getString();
3514 result->EvalType = CXEval_ObjCStrLiteral;
3515 } else {
3516 StrE = cast<StringLiteral>(I->getSubExprAsWritten());
3517 result->EvalType = CXEval_StrLiteral;
3518 }
3519
3520 std::string strRef(StrE->getString().str());
3521 result->EvalData.stringVal = (char *)malloc(strRef.size()+1);
3522 strncpy((char*)result->EvalData.stringVal, strRef.c_str(),
3523 strRef.size());
3524 result->EvalData.stringVal[strRef.size()] = '\0';
3525 return result;
3526 }
3527
3528 } else if (expr->getStmtClass() == Stmt::ObjCStringLiteralClass ||
3529 expr->getStmtClass() == Stmt::StringLiteralClass) {
3530
3531 const StringLiteral *StrE = nullptr;
3532 const ObjCStringLiteral *ObjCExpr;
3533 ObjCExpr = dyn_cast<ObjCStringLiteral>(expr);
3534
3535 if (ObjCExpr) {
3536 StrE = ObjCExpr->getString();
3537 result->EvalType = CXEval_ObjCStrLiteral;
3538 } else {
3539 StrE = cast<StringLiteral>(expr);
3540 result->EvalType = CXEval_StrLiteral;
3541 }
3542
3543 std::string strRef(StrE->getString().str());
3544 result->EvalData.stringVal = (char *)malloc(strRef.size()+1);
3545 strncpy((char*)result->EvalData.stringVal, strRef.c_str(),
3546 strRef.size());
3547 result->EvalData.stringVal[strRef.size()] = '\0';
3548 return result;
3549
3550 } else if (expr->getStmtClass() == Stmt::CStyleCastExprClass) {
3551
3552 CStyleCastExpr *CC = static_cast<CStyleCastExpr *>(expr);
3553
3554 rettype = CC->getType();
3555 if (rettype.getAsString() == "CFStringRef" &&
3556 CC->getSubExpr()->getStmtClass() == Stmt::CallExprClass) {
3557
3558 callExpr = static_cast<CallExpr *>(CC->getSubExpr());
3559 StringLiteral* S = getCFSTR_value(callExpr);
3560 if (S) {
3561 std::string strLiteral(S->getString().str());
3562 result->EvalType = CXEval_CFStr;
3563
3564 result->EvalData.stringVal = (char *)malloc(strLiteral.size()+1);
3565 strncpy((char*)result->EvalData.stringVal, strLiteral.c_str(),
3566 strLiteral.size());
3567 result->EvalData.stringVal[strLiteral.size()] = '\0';
3568 return result;
3569 }
3570 }
3571
3572 } else if (expr->getStmtClass() == Stmt::CallExprClass) {
3573
3574 callExpr = static_cast<CallExpr *>(expr);
3575 rettype = callExpr->getCallReturnType(ctx);
3576
3577 if (rettype->isVectorType() || callExpr->getNumArgs() > 1) {
3578 return nullptr;
3579 }
3580 if (rettype->isIntegralType(ctx) || rettype->isRealFloatingType()) {
3581 if(callExpr->getNumArgs() == 1 &&
3582 !callExpr->getArg(0)->getType()->isIntegralType(ctx)){
3583
3584 return nullptr;
3585 }
3586 } else if(rettype.getAsString() == "CFStringRef") {
3587
3588 StringLiteral* S = getCFSTR_value(callExpr);
3589 if (S) {
3590 std::string strLiteral(S->getString().str());
3591 result->EvalType = CXEval_CFStr;
3592 result->EvalData.stringVal = (char *)malloc(strLiteral.size()+1);
3593 strncpy((char*)result->EvalData.stringVal, strLiteral.c_str(),
3594 strLiteral.size());
3595 result->EvalData.stringVal[strLiteral.size()] = '\0';
3596 return result;
3597 }
3598 }
3599
3600 } else if (expr->getStmtClass() == Stmt::DeclRefExprClass) {
3601
3602 DeclRefExpr *D = static_cast<DeclRefExpr *>(expr);
3603 ValueDecl *V = D->getDecl();
3604 if (V->getKind() == Decl::Function) {
3605 std::string strName(V->getNameAsString());
3606 result->EvalType = CXEval_Other;
3607 result->EvalData.stringVal = (char *)malloc(strName.size()+1);
3608 strncpy((char*)result->EvalData.stringVal, strName.c_str(),
3609 strName.size());
3610 result->EvalData.stringVal[strName.size()] = '\0';
3611 return result;
3612 }
3613 }
3614
3615 }
3616
3617 clang_EvalResult_dispose((CXEvalResult *)result);
3618 return nullptr;
3619}
3620
3621CXEvalResult clang_Cursor_Evaluate(CXCursor C) {
3622 const Decl *D = getCursorDecl(C);
3623 if (D) {
3624 const Expr *expr = nullptr;
3625 if (auto *Var = dyn_cast<VarDecl>(D)) {
3626 expr = Var->getInit();
3627 } else if (auto *Field = dyn_cast<FieldDecl>(D)) {
3628 expr = Field->getInClassInitializer();
3629 }
3630 if (expr)
Aaron Ballman01dc1572016-01-20 15:25:30 +00003631 return const_cast<CXEvalResult>(reinterpret_cast<const void *>(
3632 evaluateExpr(const_cast<Expr *>(expr), C)));
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003633 return nullptr;
3634 }
3635
3636 const CompoundStmt *compoundStmt = dyn_cast_or_null<CompoundStmt>(getCursorStmt(C));
3637 if (compoundStmt) {
3638 Expr *expr = nullptr;
3639 for (auto *bodyIterator : compoundStmt->body()) {
3640 if ((expr = dyn_cast<Expr>(bodyIterator))) {
3641 break;
3642 }
3643 }
3644 if (expr)
Aaron Ballman01dc1572016-01-20 15:25:30 +00003645 return const_cast<CXEvalResult>(
3646 reinterpret_cast<const void *>(evaluateExpr(expr, C)));
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003647 }
3648 return nullptr;
3649}
3650
3651unsigned clang_Cursor_hasAttrs(CXCursor C) {
3652 const Decl *D = getCursorDecl(C);
3653 if (!D) {
3654 return 0;
3655 }
3656
3657 if (D->hasAttrs()) {
3658 return 1;
3659 }
3660
3661 return 0;
3662}
Guy Benyei11169dd2012-12-18 14:30:41 +00003663unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
3664 return CXSaveTranslationUnit_None;
3665}
3666
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003667static CXSaveError clang_saveTranslationUnit_Impl(CXTranslationUnit TU,
3668 const char *FileName,
3669 unsigned options) {
3670 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003671 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3672 setThreadBackgroundPriority();
3673
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003674 bool hadError = cxtu::getASTUnit(TU)->Save(FileName);
3675 return hadError ? CXSaveError_Unknown : CXSaveError_None;
Guy Benyei11169dd2012-12-18 14:30:41 +00003676}
3677
3678int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3679 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003680 LOG_FUNC_SECTION {
3681 *Log << TU << ' ' << FileName;
3682 }
3683
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003684 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003685 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003686 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003687 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003688
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003689 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003690 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3691 if (!CXXUnit->hasSema())
3692 return CXSaveError_InvalidTU;
3693
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003694 CXSaveError result;
3695 auto SaveTranslationUnitImpl = [=, &result]() {
3696 result = clang_saveTranslationUnit_Impl(TU, FileName, options);
3697 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003698
3699 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3700 getenv("LIBCLANG_NOTHREADS")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003701 SaveTranslationUnitImpl();
Guy Benyei11169dd2012-12-18 14:30:41 +00003702
3703 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3704 PrintLibclangResourceUsage(TU);
3705
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003706 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003707 }
3708
3709 // We have an AST that has invalid nodes due to compiler errors.
3710 // Use a crash recovery thread for protection.
3711
3712 llvm::CrashRecoveryContext CRC;
3713
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003714 if (!RunSafely(CRC, SaveTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003715 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3716 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3717 fprintf(stderr, " 'options' : %d,\n", options);
3718 fprintf(stderr, "}\n");
3719
3720 return CXSaveError_Unknown;
3721
3722 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3723 PrintLibclangResourceUsage(TU);
3724 }
3725
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003726 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003727}
3728
3729void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3730 if (CTUnit) {
3731 // If the translation unit has been marked as unsafe to free, just discard
3732 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003733 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3734 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003735 return;
3736
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003737 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003738 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003739 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3740 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003741 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003742 delete CTUnit;
3743 }
3744}
3745
3746unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3747 return CXReparse_None;
3748}
3749
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003750static CXErrorCode
3751clang_reparseTranslationUnit_Impl(CXTranslationUnit TU,
3752 ArrayRef<CXUnsavedFile> unsaved_files,
3753 unsigned options) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003754 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003755 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003756 LOG_BAD_TU(TU);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003757 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003758 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003759
3760 // Reset the associated diagnostics.
3761 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003762 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003763
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003764 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003765 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3766 setThreadBackgroundPriority();
3767
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003768 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003769 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003770
3771 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3772 new std::vector<ASTUnit::RemappedFile>());
3773
Guy Benyei11169dd2012-12-18 14:30:41 +00003774 // Recover resources if we crash before exiting this function.
3775 llvm::CrashRecoveryContextCleanupRegistrar<
3776 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003777
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003778 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003779 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003780 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003781 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003782 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003783
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003784 if (!CXXUnit->Reparse(CXXIdx->getPCHContainerOperations(),
3785 *RemappedFiles.get()))
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003786 return CXError_Success;
3787 if (isASTReadError(CXXUnit))
3788 return CXError_ASTReadError;
3789 return CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003790}
3791
3792int clang_reparseTranslationUnit(CXTranslationUnit TU,
3793 unsigned num_unsaved_files,
3794 struct CXUnsavedFile *unsaved_files,
3795 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003796 LOG_FUNC_SECTION {
3797 *Log << TU;
3798 }
3799
Alp Toker9d85b182014-07-07 01:23:14 +00003800 if (num_unsaved_files && !unsaved_files)
3801 return CXError_InvalidArguments;
3802
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003803 CXErrorCode result;
3804 auto ReparseTranslationUnitImpl = [=, &result]() {
3805 result = clang_reparseTranslationUnit_Impl(
3806 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options);
3807 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003808
3809 if (getenv("LIBCLANG_NOTHREADS")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003810 ReparseTranslationUnitImpl();
Alp Toker5c532982014-07-07 22:42:03 +00003811 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003812 }
3813
3814 llvm::CrashRecoveryContext CRC;
3815
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003816 if (!RunSafely(CRC, ReparseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003817 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003818 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003819 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003820 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3821 PrintLibclangResourceUsage(TU);
3822
Alp Toker5c532982014-07-07 22:42:03 +00003823 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003824}
3825
3826
3827CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003828 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003829 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003830 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003831 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003832
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003833 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003834 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003835}
3836
3837CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003838 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003839 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003840 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003841 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003842
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003843 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003844 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3845}
3846
3847} // end: extern "C"
3848
3849//===----------------------------------------------------------------------===//
3850// CXFile Operations.
3851//===----------------------------------------------------------------------===//
3852
3853extern "C" {
3854CXString clang_getFileName(CXFile SFile) {
3855 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003856 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003857
3858 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003859 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003860}
3861
3862time_t clang_getFileTime(CXFile SFile) {
3863 if (!SFile)
3864 return 0;
3865
3866 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3867 return FEnt->getModificationTime();
3868}
3869
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003870CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003871 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003872 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003873 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003874 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003875
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003876 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003877
3878 FileManager &FMgr = CXXUnit->getFileManager();
3879 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3880}
3881
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003882unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3883 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003884 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003885 LOG_BAD_TU(TU);
3886 return 0;
3887 }
3888
3889 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003890 return 0;
3891
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003892 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003893 FileEntry *FEnt = static_cast<FileEntry *>(file);
3894 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3895 .isFileMultipleIncludeGuarded(FEnt);
3896}
3897
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003898int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3899 if (!file || !outID)
3900 return 1;
3901
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003902 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003903 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3904 outID->data[0] = ID.getDevice();
3905 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003906 outID->data[2] = FEnt->getModificationTime();
3907 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003908}
3909
Argyrios Kyrtzidisac3997e2014-08-16 00:26:19 +00003910int clang_File_isEqual(CXFile file1, CXFile file2) {
3911 if (file1 == file2)
3912 return true;
3913
3914 if (!file1 || !file2)
3915 return false;
3916
3917 FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
3918 FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
3919 return FEnt1->getUniqueID() == FEnt2->getUniqueID();
3920}
3921
Guy Benyei11169dd2012-12-18 14:30:41 +00003922} // end: extern "C"
3923
3924//===----------------------------------------------------------------------===//
3925// CXCursor Operations.
3926//===----------------------------------------------------------------------===//
3927
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003928static const Decl *getDeclFromExpr(const Stmt *E) {
3929 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003930 return getDeclFromExpr(CE->getSubExpr());
3931
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003932 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003933 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003934 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003935 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003936 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003937 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003938 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003939 if (PRE->isExplicitProperty())
3940 return PRE->getExplicitProperty();
3941 // It could be messaging both getter and setter as in:
3942 // ++myobj.myprop;
3943 // in which case prefer to associate the setter since it is less obvious
3944 // from inspecting the source that the setter is going to get called.
3945 if (PRE->isMessagingSetter())
3946 return PRE->getImplicitPropertySetter();
3947 return PRE->getImplicitPropertyGetter();
3948 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003949 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003950 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003951 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003952 if (Expr *Src = OVE->getSourceExpr())
3953 return getDeclFromExpr(Src);
3954
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003955 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003956 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003957 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003958 if (!CE->isElidable())
3959 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003960 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003961 return OME->getMethodDecl();
3962
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003963 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003964 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003965 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003966 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3967 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003968 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003969 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3970 isa<ParmVarDecl>(SizeOfPack->getPack()))
3971 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003972
3973 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003974}
3975
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003976static SourceLocation getLocationFromExpr(const Expr *E) {
3977 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003978 return getLocationFromExpr(CE->getSubExpr());
3979
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003980 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003981 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003982 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003983 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003984 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003985 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003986 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003987 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003988 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003989 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003990 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003991 return PropRef->getLocation();
3992
3993 return E->getLocStart();
3994}
3995
3996extern "C" {
3997
3998unsigned clang_visitChildren(CXCursor parent,
3999 CXCursorVisitor visitor,
4000 CXClientData client_data) {
4001 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
4002 /*VisitPreprocessorLast=*/false);
4003 return CursorVis.VisitChildren(parent);
4004}
4005
4006#ifndef __has_feature
4007#define __has_feature(x) 0
4008#endif
4009#if __has_feature(blocks)
4010typedef enum CXChildVisitResult
4011 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
4012
4013static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
4014 CXClientData client_data) {
4015 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
4016 return block(cursor, parent);
4017}
4018#else
4019// If we are compiled with a compiler that doesn't have native blocks support,
4020// define and call the block manually, so the
4021typedef struct _CXChildVisitResult
4022{
4023 void *isa;
4024 int flags;
4025 int reserved;
4026 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
4027 CXCursor);
4028} *CXCursorVisitorBlock;
4029
4030static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
4031 CXClientData client_data) {
4032 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
4033 return block->invoke(block, cursor, parent);
4034}
4035#endif
4036
4037
4038unsigned clang_visitChildrenWithBlock(CXCursor parent,
4039 CXCursorVisitorBlock block) {
4040 return clang_visitChildren(parent, visitWithBlock, block);
4041}
4042
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004043static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004044 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004045 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004046
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004047 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004048 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004049 if (const ObjCPropertyImplDecl *PropImpl =
4050 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004051 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004052 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004053
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004054 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004055 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004056 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004057
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004058 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004059 }
4060
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004061 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004062 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004063
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004064 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00004065 // No, this isn't the same as the code below. getIdentifier() is non-virtual
4066 // and returns different names. NamedDecl returns the class name and
4067 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004068 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004069
4070 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004071 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004072
4073 SmallString<1024> S;
4074 llvm::raw_svector_ostream os(S);
4075 ND->printName(os);
4076
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004077 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004078}
4079
4080CXString clang_getCursorSpelling(CXCursor C) {
4081 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00004082 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004083
4084 if (clang_isReference(C.kind)) {
4085 switch (C.kind) {
4086 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004087 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004088 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004089 }
4090 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004091 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004092 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004093 }
4094 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004095 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004096 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004097 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004098 }
4099 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004100 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004101 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004102 }
4103 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004104 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004105 assert(Type && "Missing type decl");
4106
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004107 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00004108 getAsString());
4109 }
4110 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004111 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004112 assert(Template && "Missing template decl");
4113
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004114 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004115 }
4116
4117 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004118 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004119 assert(NS && "Missing namespace decl");
4120
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004121 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004122 }
4123
4124 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004125 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004126 assert(Field && "Missing member decl");
4127
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004128 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004129 }
4130
4131 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004132 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004133 assert(Label && "Missing label");
4134
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004135 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004136 }
4137
4138 case CXCursor_OverloadedDeclRef: {
4139 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004140 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
4141 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004142 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004143 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004144 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004145 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004146 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004147 OverloadedTemplateStorage *Ovl
4148 = Storage.get<OverloadedTemplateStorage*>();
4149 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004150 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004151 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004152 }
4153
4154 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004155 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004156 assert(Var && "Missing variable decl");
4157
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004158 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004159 }
4160
4161 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004162 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00004163 }
4164 }
4165
4166 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00004167 const Expr *E = getCursorExpr(C);
4168
4169 if (C.kind == CXCursor_ObjCStringLiteral ||
4170 C.kind == CXCursor_StringLiteral) {
4171 const StringLiteral *SLit;
4172 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
4173 SLit = OSL->getString();
4174 } else {
4175 SLit = cast<StringLiteral>(E);
4176 }
4177 SmallString<256> Buf;
4178 llvm::raw_svector_ostream OS(Buf);
4179 SLit->outputString(OS);
4180 return cxstring::createDup(OS.str());
4181 }
4182
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004183 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004184 if (D)
4185 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004186 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004187 }
4188
4189 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004190 const Stmt *S = getCursorStmt(C);
4191 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004192 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004193
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004194 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004195 }
4196
4197 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004198 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00004199 ->getNameStart());
4200
4201 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004202 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00004203 ->getNameStart());
4204
4205 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004206 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004207
4208 if (clang_isDeclaration(C.kind))
4209 return getDeclSpelling(getCursorDecl(C));
4210
4211 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00004212 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004213 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00004214 }
4215
4216 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00004217 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004218 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00004219 }
4220
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004221 if (C.kind == CXCursor_PackedAttr) {
4222 return cxstring::createRef("packed");
4223 }
4224
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00004225 if (C.kind == CXCursor_VisibilityAttr) {
4226 const VisibilityAttr *AA = cast<VisibilityAttr>(cxcursor::getCursorAttr(C));
4227 switch (AA->getVisibility()) {
4228 case VisibilityAttr::VisibilityType::Default:
4229 return cxstring::createRef("default");
4230 case VisibilityAttr::VisibilityType::Hidden:
4231 return cxstring::createRef("hidden");
4232 case VisibilityAttr::VisibilityType::Protected:
4233 return cxstring::createRef("protected");
4234 }
4235 llvm_unreachable("unknown visibility type");
4236 }
4237
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004238 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004239}
4240
4241CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
4242 unsigned pieceIndex,
4243 unsigned options) {
4244 if (clang_Cursor_isNull(C))
4245 return clang_getNullRange();
4246
4247 ASTContext &Ctx = getCursorContext(C);
4248
4249 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004250 const Stmt *S = getCursorStmt(C);
4251 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004252 if (pieceIndex > 0)
4253 return clang_getNullRange();
4254 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
4255 }
4256
4257 return clang_getNullRange();
4258 }
4259
4260 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004261 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00004262 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
4263 if (pieceIndex >= ME->getNumSelectorLocs())
4264 return clang_getNullRange();
4265 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
4266 }
4267 }
4268
4269 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
4270 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004271 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00004272 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
4273 if (pieceIndex >= MD->getNumSelectorLocs())
4274 return clang_getNullRange();
4275 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
4276 }
4277 }
4278
4279 if (C.kind == CXCursor_ObjCCategoryDecl ||
4280 C.kind == CXCursor_ObjCCategoryImplDecl) {
4281 if (pieceIndex > 0)
4282 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004283 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00004284 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
4285 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004286 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00004287 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
4288 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
4289 }
4290
4291 if (C.kind == CXCursor_ModuleImportDecl) {
4292 if (pieceIndex > 0)
4293 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004294 if (const ImportDecl *ImportD =
4295 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004296 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
4297 if (!Locs.empty())
4298 return cxloc::translateSourceRange(Ctx,
4299 SourceRange(Locs.front(), Locs.back()));
4300 }
4301 return clang_getNullRange();
4302 }
4303
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00004304 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
4305 C.kind == CXCursor_ConversionFunction) {
4306 if (pieceIndex > 0)
4307 return clang_getNullRange();
4308 if (const FunctionDecl *FD =
4309 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
4310 DeclarationNameInfo FunctionName = FD->getNameInfo();
4311 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
4312 }
4313 return clang_getNullRange();
4314 }
4315
Guy Benyei11169dd2012-12-18 14:30:41 +00004316 // FIXME: A CXCursor_InclusionDirective should give the location of the
4317 // filename, but we don't keep track of this.
4318
4319 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
4320 // but we don't keep track of this.
4321
4322 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
4323 // but we don't keep track of this.
4324
4325 // Default handling, give the location of the cursor.
4326
4327 if (pieceIndex > 0)
4328 return clang_getNullRange();
4329
4330 CXSourceLocation CXLoc = clang_getCursorLocation(C);
4331 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
4332 return cxloc::translateSourceRange(Ctx, Loc);
4333}
4334
Eli Bendersky44a206f2014-07-31 18:04:56 +00004335CXString clang_Cursor_getMangling(CXCursor C) {
4336 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
4337 return cxstring::createEmpty();
4338
Eli Bendersky44a206f2014-07-31 18:04:56 +00004339 // Mangling only works for functions and variables.
Eli Bendersky79759592014-08-01 15:01:10 +00004340 const Decl *D = getCursorDecl(C);
Eli Bendersky44a206f2014-07-31 18:04:56 +00004341 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
4342 return cxstring::createEmpty();
4343
Argyrios Kyrtzidisca741ce2016-02-14 22:30:14 +00004344 ASTContext &Ctx = D->getASTContext();
4345 index::CodegenNameGenerator CGNameGen(Ctx);
4346 return cxstring::createDup(CGNameGen.getName(D));
Eli Bendersky44a206f2014-07-31 18:04:56 +00004347}
4348
Saleem Abdulrasool60034432015-11-12 03:57:22 +00004349CXStringSet *clang_Cursor_getCXXManglings(CXCursor C) {
4350 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
4351 return nullptr;
4352
4353 const Decl *D = getCursorDecl(C);
4354 if (!(isa<CXXRecordDecl>(D) || isa<CXXMethodDecl>(D)))
4355 return nullptr;
4356
Argyrios Kyrtzidisca741ce2016-02-14 22:30:14 +00004357 ASTContext &Ctx = D->getASTContext();
4358 index::CodegenNameGenerator CGNameGen(Ctx);
4359 std::vector<std::string> Manglings = CGNameGen.getAllManglings(D);
Saleem Abdulrasool60034432015-11-12 03:57:22 +00004360 return cxstring::createSet(Manglings);
4361}
4362
Guy Benyei11169dd2012-12-18 14:30:41 +00004363CXString clang_getCursorDisplayName(CXCursor C) {
4364 if (!clang_isDeclaration(C.kind))
4365 return clang_getCursorSpelling(C);
4366
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004367 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004368 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004369 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004370
4371 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004372 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004373 D = FunTmpl->getTemplatedDecl();
4374
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004375 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004376 SmallString<64> Str;
4377 llvm::raw_svector_ostream OS(Str);
4378 OS << *Function;
4379 if (Function->getPrimaryTemplate())
4380 OS << "<>";
4381 OS << "(";
4382 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
4383 if (I)
4384 OS << ", ";
4385 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
4386 }
4387
4388 if (Function->isVariadic()) {
4389 if (Function->getNumParams())
4390 OS << ", ";
4391 OS << "...";
4392 }
4393 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004394 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004395 }
4396
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004397 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004398 SmallString<64> Str;
4399 llvm::raw_svector_ostream OS(Str);
4400 OS << *ClassTemplate;
4401 OS << "<";
4402 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
4403 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
4404 if (I)
4405 OS << ", ";
4406
4407 NamedDecl *Param = Params->getParam(I);
4408 if (Param->getIdentifier()) {
4409 OS << Param->getIdentifier()->getName();
4410 continue;
4411 }
4412
4413 // There is no parameter name, which makes this tricky. Try to come up
4414 // with something useful that isn't too long.
4415 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
4416 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
4417 else if (NonTypeTemplateParmDecl *NTTP
4418 = dyn_cast<NonTypeTemplateParmDecl>(Param))
4419 OS << NTTP->getType().getAsString(Policy);
4420 else
4421 OS << "template<...> class";
4422 }
4423
4424 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004425 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004426 }
4427
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004428 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00004429 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
4430 // If the type was explicitly written, use that.
4431 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004432 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00004433
Benjamin Kramer9170e912013-02-22 15:46:01 +00004434 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00004435 llvm::raw_svector_ostream OS(Str);
4436 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00004437 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00004438 ClassSpec->getTemplateArgs().data(),
4439 ClassSpec->getTemplateArgs().size(),
4440 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004441 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004442 }
4443
4444 return clang_getCursorSpelling(C);
4445}
4446
4447CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
4448 switch (Kind) {
4449 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004450 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004451 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004452 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004453 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004454 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004455 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004456 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004457 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004458 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004459 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004460 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004461 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004462 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004463 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004464 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004465 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004466 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004467 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004468 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004469 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004470 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004471 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004472 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004473 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004474 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004475 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004476 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004477 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004478 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004479 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004480 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004481 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004482 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004483 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004484 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004485 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004486 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004487 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004488 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00004489 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004490 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004491 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004492 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004493 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004494 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004495 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004496 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004497 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004498 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004499 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004500 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004501 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004502 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004503 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004504 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004505 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004506 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004507 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004508 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004509 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004510 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004511 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004512 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004513 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004514 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004515 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004516 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004517 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004518 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004519 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004520 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004521 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004522 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004523 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004524 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004525 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004526 return cxstring::createRef("ArraySubscriptExpr");
Alexey Bataev1a3320e2015-08-25 14:24:04 +00004527 case CXCursor_OMPArraySectionExpr:
4528 return cxstring::createRef("OMPArraySectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004529 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004530 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004531 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004532 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004533 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004534 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004535 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004536 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004537 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004538 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004539 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004540 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004541 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004542 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004543 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004544 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004545 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004546 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004547 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004548 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004549 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004550 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004551 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004552 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004553 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004554 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004555 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004556 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004557 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004558 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004559 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004560 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004561 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004562 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004563 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004564 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004565 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004566 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004567 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004568 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004569 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004570 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004571 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004572 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004573 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004574 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004575 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004576 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004577 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004578 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00004579 case CXCursor_ObjCSelfExpr:
4580 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004581 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004582 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004583 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004584 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004585 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004586 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004587 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004588 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004589 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004590 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004591 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004592 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004593 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004594 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004595 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004596 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004597 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004598 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004599 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004600 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004601 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004602 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004603 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004604 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004605 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004606 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004607 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004608 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004609 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004610 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004611 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004612 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004613 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004614 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004615 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004616 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004617 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004618 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004619 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004620 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004621 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004622 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004623 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004624 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004625 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004626 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004627 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004628 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004629 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004630 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004631 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004632 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004633 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004634 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004635 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004636 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004637 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004638 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004639 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004640 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004641 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004642 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004643 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004644 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004645 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004646 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004647 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004648 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004649 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004650 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004651 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004652 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004653 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004654 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004655 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004656 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004657 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004658 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004659 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004660 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004661 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004662 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004663 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004664 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004665 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004666 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004667 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004668 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00004669 case CXCursor_SEHLeaveStmt:
4670 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004671 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004672 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004673 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004674 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00004675 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004676 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00004677 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004678 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00004679 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004680 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00004681 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004682 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00004683 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004684 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004685 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004686 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004687 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004688 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004689 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004690 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004691 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004692 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004693 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004694 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004695 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004696 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004697 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004698 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004699 case CXCursor_PackedAttr:
4700 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00004701 case CXCursor_PureAttr:
4702 return cxstring::createRef("attribute(pure)");
4703 case CXCursor_ConstAttr:
4704 return cxstring::createRef("attribute(const)");
4705 case CXCursor_NoDuplicateAttr:
4706 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00004707 case CXCursor_CUDAConstantAttr:
4708 return cxstring::createRef("attribute(constant)");
4709 case CXCursor_CUDADeviceAttr:
4710 return cxstring::createRef("attribute(device)");
4711 case CXCursor_CUDAGlobalAttr:
4712 return cxstring::createRef("attribute(global)");
4713 case CXCursor_CUDAHostAttr:
4714 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00004715 case CXCursor_CUDASharedAttr:
4716 return cxstring::createRef("attribute(shared)");
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00004717 case CXCursor_VisibilityAttr:
4718 return cxstring::createRef("attribute(visibility)");
Saleem Abdulrasool8aa0b802015-12-10 18:45:18 +00004719 case CXCursor_DLLExport:
4720 return cxstring::createRef("attribute(dllexport)");
4721 case CXCursor_DLLImport:
4722 return cxstring::createRef("attribute(dllimport)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004723 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004724 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004725 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004726 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00004727 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004728 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004729 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004730 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004731 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004732 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00004733 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004734 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00004735 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004736 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004737 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004738 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004739 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004740 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004741 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004742 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004743 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004744 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004745 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004746 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004747 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004748 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004749 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004750 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004751 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004752 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004753 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004754 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004755 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004756 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004757 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004758 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004759 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004760 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004761 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004762 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004763 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004764 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004765 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004766 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004767 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004768 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004769 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004770 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004771 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004772 return cxstring::createRef("OMPParallelDirective");
4773 case CXCursor_OMPSimdDirective:
4774 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004775 case CXCursor_OMPForDirective:
4776 return cxstring::createRef("OMPForDirective");
Alexander Musmanf82886e2014-09-18 05:12:34 +00004777 case CXCursor_OMPForSimdDirective:
4778 return cxstring::createRef("OMPForSimdDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004779 case CXCursor_OMPSectionsDirective:
4780 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004781 case CXCursor_OMPSectionDirective:
4782 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004783 case CXCursor_OMPSingleDirective:
4784 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004785 case CXCursor_OMPMasterDirective:
4786 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004787 case CXCursor_OMPCriticalDirective:
4788 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004789 case CXCursor_OMPParallelForDirective:
4790 return cxstring::createRef("OMPParallelForDirective");
Alexander Musmane4e893b2014-09-23 09:33:00 +00004791 case CXCursor_OMPParallelForSimdDirective:
4792 return cxstring::createRef("OMPParallelForSimdDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004793 case CXCursor_OMPParallelSectionsDirective:
4794 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004795 case CXCursor_OMPTaskDirective:
4796 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004797 case CXCursor_OMPTaskyieldDirective:
4798 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004799 case CXCursor_OMPBarrierDirective:
4800 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004801 case CXCursor_OMPTaskwaitDirective:
4802 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00004803 case CXCursor_OMPTaskgroupDirective:
4804 return cxstring::createRef("OMPTaskgroupDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00004805 case CXCursor_OMPFlushDirective:
4806 return cxstring::createRef("OMPFlushDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004807 case CXCursor_OMPOrderedDirective:
4808 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00004809 case CXCursor_OMPAtomicDirective:
4810 return cxstring::createRef("OMPAtomicDirective");
Alexey Bataev0bd520b2014-09-19 08:19:49 +00004811 case CXCursor_OMPTargetDirective:
4812 return cxstring::createRef("OMPTargetDirective");
Michael Wong65f367f2015-07-21 13:44:28 +00004813 case CXCursor_OMPTargetDataDirective:
4814 return cxstring::createRef("OMPTargetDataDirective");
Samuel Antaodf67fc42016-01-19 19:15:56 +00004815 case CXCursor_OMPTargetEnterDataDirective:
4816 return cxstring::createRef("OMPTargetEnterDataDirective");
Samuel Antao72590762016-01-19 20:04:50 +00004817 case CXCursor_OMPTargetExitDataDirective:
4818 return cxstring::createRef("OMPTargetExitDataDirective");
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00004819 case CXCursor_OMPTargetParallelDirective:
4820 return cxstring::createRef("OMPTargetParallelDirective");
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00004821 case CXCursor_OMPTargetParallelForDirective:
4822 return cxstring::createRef("OMPTargetParallelForDirective");
Alexey Bataev13314bf2014-10-09 04:18:56 +00004823 case CXCursor_OMPTeamsDirective:
4824 return cxstring::createRef("OMPTeamsDirective");
Alexey Bataev6d4ed052015-07-01 06:57:41 +00004825 case CXCursor_OMPCancellationPointDirective:
4826 return cxstring::createRef("OMPCancellationPointDirective");
Alexey Bataev80909872015-07-02 11:25:17 +00004827 case CXCursor_OMPCancelDirective:
4828 return cxstring::createRef("OMPCancelDirective");
Alexey Bataev49f6e782015-12-01 04:18:41 +00004829 case CXCursor_OMPTaskLoopDirective:
4830 return cxstring::createRef("OMPTaskLoopDirective");
Alexey Bataev0a6ed842015-12-03 09:40:15 +00004831 case CXCursor_OMPTaskLoopSimdDirective:
4832 return cxstring::createRef("OMPTaskLoopSimdDirective");
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00004833 case CXCursor_OMPDistributeDirective:
4834 return cxstring::createRef("OMPDistributeDirective");
Francisco Lopes da Silva975a9f62015-01-21 16:24:11 +00004835 case CXCursor_OverloadCandidate:
4836 return cxstring::createRef("OverloadCandidate");
Sergey Kalinichev8f3b1872015-11-15 13:48:32 +00004837 case CXCursor_TypeAliasTemplateDecl:
4838 return cxstring::createRef("TypeAliasTemplateDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004839 }
4840
4841 llvm_unreachable("Unhandled CXCursorKind");
4842}
4843
4844struct GetCursorData {
4845 SourceLocation TokenBeginLoc;
4846 bool PointsAtMacroArgExpansion;
4847 bool VisitedObjCPropertyImplDecl;
4848 SourceLocation VisitedDeclaratorDeclStartLoc;
4849 CXCursor &BestCursor;
4850
4851 GetCursorData(SourceManager &SM,
4852 SourceLocation tokenBegin, CXCursor &outputCursor)
4853 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4854 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4855 VisitedObjCPropertyImplDecl = false;
4856 }
4857};
4858
4859static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4860 CXCursor parent,
4861 CXClientData client_data) {
4862 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4863 CXCursor *BestCursor = &Data->BestCursor;
4864
4865 // If we point inside a macro argument we should provide info of what the
4866 // token is so use the actual cursor, don't replace it with a macro expansion
4867 // cursor.
4868 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4869 return CXChildVisit_Recurse;
4870
4871 if (clang_isDeclaration(cursor.kind)) {
4872 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004873 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004874 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4875 if (MD->isImplicit())
4876 return CXChildVisit_Break;
4877
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004878 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004879 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4880 // Check that when we have multiple @class references in the same line,
4881 // that later ones do not override the previous ones.
4882 // If we have:
4883 // @class Foo, Bar;
4884 // source ranges for both start at '@', so 'Bar' will end up overriding
4885 // 'Foo' even though the cursor location was at 'Foo'.
4886 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4887 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004888 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004889 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4890 if (PrevID != ID &&
4891 !PrevID->isThisDeclarationADefinition() &&
4892 !ID->isThisDeclarationADefinition())
4893 return CXChildVisit_Break;
4894 }
4895
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004896 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004897 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4898 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4899 // Check that when we have multiple declarators in the same line,
4900 // that later ones do not override the previous ones.
4901 // If we have:
4902 // int Foo, Bar;
4903 // source ranges for both start at 'int', so 'Bar' will end up overriding
4904 // 'Foo' even though the cursor location was at 'Foo'.
4905 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4906 return CXChildVisit_Break;
4907 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4908
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004909 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004910 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4911 (void)PropImp;
4912 // Check that when we have multiple @synthesize in the same line,
4913 // that later ones do not override the previous ones.
4914 // If we have:
4915 // @synthesize Foo, Bar;
4916 // source ranges for both start at '@', so 'Bar' will end up overriding
4917 // 'Foo' even though the cursor location was at 'Foo'.
4918 if (Data->VisitedObjCPropertyImplDecl)
4919 return CXChildVisit_Break;
4920 Data->VisitedObjCPropertyImplDecl = true;
4921 }
4922 }
4923
4924 if (clang_isExpression(cursor.kind) &&
4925 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004926 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004927 // Avoid having the cursor of an expression replace the declaration cursor
4928 // when the expression source range overlaps the declaration range.
4929 // This can happen for C++ constructor expressions whose range generally
4930 // include the variable declaration, e.g.:
4931 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4932 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4933 D->getLocation() == Data->TokenBeginLoc)
4934 return CXChildVisit_Break;
4935 }
4936 }
4937
4938 // If our current best cursor is the construction of a temporary object,
4939 // don't replace that cursor with a type reference, because we want
4940 // clang_getCursor() to point at the constructor.
4941 if (clang_isExpression(BestCursor->kind) &&
4942 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4943 cursor.kind == CXCursor_TypeRef) {
4944 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4945 // as having the actual point on the type reference.
4946 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4947 return CXChildVisit_Recurse;
4948 }
Douglas Gregore9d95f12015-07-07 03:57:35 +00004949
4950 // If we already have an Objective-C superclass reference, don't
4951 // update it further.
4952 if (BestCursor->kind == CXCursor_ObjCSuperClassRef)
4953 return CXChildVisit_Break;
4954
Guy Benyei11169dd2012-12-18 14:30:41 +00004955 *BestCursor = cursor;
4956 return CXChildVisit_Recurse;
4957}
4958
4959CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004960 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004961 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004962 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004963 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004964
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004965 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004966 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4967
4968 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4969 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4970
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004971 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004972 CXFile SearchFile;
4973 unsigned SearchLine, SearchColumn;
4974 CXFile ResultFile;
4975 unsigned ResultLine, ResultColumn;
4976 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4977 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4978 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004979
4980 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4981 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004982 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004983 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004984 SearchFileName = clang_getFileName(SearchFile);
4985 ResultFileName = clang_getFileName(ResultFile);
4986 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4987 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004988 *Log << llvm::format("(%s:%d:%d) = %s",
4989 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4990 clang_getCString(KindSpelling))
4991 << llvm::format("(%s:%d:%d):%s%s",
4992 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4993 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004994 clang_disposeString(SearchFileName);
4995 clang_disposeString(ResultFileName);
4996 clang_disposeString(KindSpelling);
4997 clang_disposeString(USR);
4998
4999 CXCursor Definition = clang_getCursorDefinition(Result);
5000 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
5001 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
5002 CXString DefinitionKindSpelling
5003 = clang_getCursorKindSpelling(Definition.kind);
5004 CXFile DefinitionFile;
5005 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005006 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00005007 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00005008 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005009 *Log << llvm::format(" -> %s(%s:%d:%d)",
5010 clang_getCString(DefinitionKindSpelling),
5011 clang_getCString(DefinitionFileName),
5012 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00005013 clang_disposeString(DefinitionFileName);
5014 clang_disposeString(DefinitionKindSpelling);
5015 }
5016 }
5017
5018 return Result;
5019}
5020
5021CXCursor clang_getNullCursor(void) {
5022 return MakeCXCursorInvalid(CXCursor_InvalidFile);
5023}
5024
5025unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005026 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
5027 // can't set consistently. For example, when visiting a DeclStmt we will set
5028 // it but we don't set it on the result of clang_getCursorDefinition for
5029 // a reference of the same declaration.
5030 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
5031 // when visiting a DeclStmt currently, the AST should be enhanced to be able
5032 // to provide that kind of info.
5033 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00005034 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005035 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00005036 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005037
Guy Benyei11169dd2012-12-18 14:30:41 +00005038 return X == Y;
5039}
5040
5041unsigned clang_hashCursor(CXCursor C) {
5042 unsigned Index = 0;
5043 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
5044 Index = 1;
5045
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005046 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00005047 std::make_pair(C.kind, C.data[Index]));
5048}
5049
5050unsigned clang_isInvalid(enum CXCursorKind K) {
5051 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
5052}
5053
5054unsigned clang_isDeclaration(enum CXCursorKind K) {
5055 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
5056 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
5057}
5058
5059unsigned clang_isReference(enum CXCursorKind K) {
5060 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
5061}
5062
5063unsigned clang_isExpression(enum CXCursorKind K) {
5064 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
5065}
5066
5067unsigned clang_isStatement(enum CXCursorKind K) {
5068 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
5069}
5070
5071unsigned clang_isAttribute(enum CXCursorKind K) {
5072 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
5073}
5074
5075unsigned clang_isTranslationUnit(enum CXCursorKind K) {
5076 return K == CXCursor_TranslationUnit;
5077}
5078
5079unsigned clang_isPreprocessing(enum CXCursorKind K) {
5080 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
5081}
5082
5083unsigned clang_isUnexposed(enum CXCursorKind K) {
5084 switch (K) {
5085 case CXCursor_UnexposedDecl:
5086 case CXCursor_UnexposedExpr:
5087 case CXCursor_UnexposedStmt:
5088 case CXCursor_UnexposedAttr:
5089 return true;
5090 default:
5091 return false;
5092 }
5093}
5094
5095CXCursorKind clang_getCursorKind(CXCursor C) {
5096 return C.kind;
5097}
5098
5099CXSourceLocation clang_getCursorLocation(CXCursor C) {
5100 if (clang_isReference(C.kind)) {
5101 switch (C.kind) {
5102 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005103 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00005104 = getCursorObjCSuperClassRef(C);
5105 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5106 }
5107
5108 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005109 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00005110 = getCursorObjCProtocolRef(C);
5111 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5112 }
5113
5114 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005115 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00005116 = getCursorObjCClassRef(C);
5117 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5118 }
5119
5120 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005121 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005122 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5123 }
5124
5125 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005126 std::pair<const TemplateDecl *, SourceLocation> P =
5127 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005128 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5129 }
5130
5131 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005132 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005133 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5134 }
5135
5136 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005137 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005138 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5139 }
5140
5141 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005142 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005143 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5144 }
5145
5146 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005147 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005148 if (!BaseSpec)
5149 return clang_getNullLocation();
5150
5151 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
5152 return cxloc::translateSourceLocation(getCursorContext(C),
5153 TSInfo->getTypeLoc().getBeginLoc());
5154
5155 return cxloc::translateSourceLocation(getCursorContext(C),
5156 BaseSpec->getLocStart());
5157 }
5158
5159 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005160 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005161 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
5162 }
5163
5164 case CXCursor_OverloadedDeclRef:
5165 return cxloc::translateSourceLocation(getCursorContext(C),
5166 getCursorOverloadedDeclRef(C).second);
5167
5168 default:
5169 // FIXME: Need a way to enumerate all non-reference cases.
5170 llvm_unreachable("Missed a reference kind");
5171 }
5172 }
5173
5174 if (clang_isExpression(C.kind))
5175 return cxloc::translateSourceLocation(getCursorContext(C),
5176 getLocationFromExpr(getCursorExpr(C)));
5177
5178 if (clang_isStatement(C.kind))
5179 return cxloc::translateSourceLocation(getCursorContext(C),
5180 getCursorStmt(C)->getLocStart());
5181
5182 if (C.kind == CXCursor_PreprocessingDirective) {
5183 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
5184 return cxloc::translateSourceLocation(getCursorContext(C), L);
5185 }
5186
5187 if (C.kind == CXCursor_MacroExpansion) {
5188 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005189 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00005190 return cxloc::translateSourceLocation(getCursorContext(C), L);
5191 }
5192
5193 if (C.kind == CXCursor_MacroDefinition) {
5194 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
5195 return cxloc::translateSourceLocation(getCursorContext(C), L);
5196 }
5197
5198 if (C.kind == CXCursor_InclusionDirective) {
5199 SourceLocation L
5200 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
5201 return cxloc::translateSourceLocation(getCursorContext(C), L);
5202 }
5203
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00005204 if (clang_isAttribute(C.kind)) {
5205 SourceLocation L
5206 = cxcursor::getCursorAttr(C)->getLocation();
5207 return cxloc::translateSourceLocation(getCursorContext(C), L);
5208 }
5209
Guy Benyei11169dd2012-12-18 14:30:41 +00005210 if (!clang_isDeclaration(C.kind))
5211 return clang_getNullLocation();
5212
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005213 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005214 if (!D)
5215 return clang_getNullLocation();
5216
5217 SourceLocation Loc = D->getLocation();
5218 // FIXME: Multiple variables declared in a single declaration
5219 // currently lack the information needed to correctly determine their
5220 // ranges when accounting for the type-specifier. We use context
5221 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
5222 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005223 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005224 if (!cxcursor::isFirstInDeclGroup(C))
5225 Loc = VD->getLocation();
5226 }
5227
5228 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005229 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005230 Loc = MD->getSelectorStartLoc();
5231
5232 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
5233}
5234
5235} // end extern "C"
5236
5237CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
5238 assert(TU);
5239
5240 // Guard against an invalid SourceLocation, or we may assert in one
5241 // of the following calls.
5242 if (SLoc.isInvalid())
5243 return clang_getNullCursor();
5244
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005245 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005246
5247 // Translate the given source location to make it point at the beginning of
5248 // the token under the cursor.
5249 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
5250 CXXUnit->getASTContext().getLangOpts());
5251
5252 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
5253 if (SLoc.isValid()) {
5254 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
5255 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
5256 /*VisitPreprocessorLast=*/true,
5257 /*VisitIncludedEntities=*/false,
5258 SourceLocation(SLoc));
5259 CursorVis.visitFileRegion();
5260 }
5261
5262 return Result;
5263}
5264
5265static SourceRange getRawCursorExtent(CXCursor C) {
5266 if (clang_isReference(C.kind)) {
5267 switch (C.kind) {
5268 case CXCursor_ObjCSuperClassRef:
5269 return getCursorObjCSuperClassRef(C).second;
5270
5271 case CXCursor_ObjCProtocolRef:
5272 return getCursorObjCProtocolRef(C).second;
5273
5274 case CXCursor_ObjCClassRef:
5275 return getCursorObjCClassRef(C).second;
5276
5277 case CXCursor_TypeRef:
5278 return getCursorTypeRef(C).second;
5279
5280 case CXCursor_TemplateRef:
5281 return getCursorTemplateRef(C).second;
5282
5283 case CXCursor_NamespaceRef:
5284 return getCursorNamespaceRef(C).second;
5285
5286 case CXCursor_MemberRef:
5287 return getCursorMemberRef(C).second;
5288
5289 case CXCursor_CXXBaseSpecifier:
5290 return getCursorCXXBaseSpecifier(C)->getSourceRange();
5291
5292 case CXCursor_LabelRef:
5293 return getCursorLabelRef(C).second;
5294
5295 case CXCursor_OverloadedDeclRef:
5296 return getCursorOverloadedDeclRef(C).second;
5297
5298 case CXCursor_VariableRef:
5299 return getCursorVariableRef(C).second;
5300
5301 default:
5302 // FIXME: Need a way to enumerate all non-reference cases.
5303 llvm_unreachable("Missed a reference kind");
5304 }
5305 }
5306
5307 if (clang_isExpression(C.kind))
5308 return getCursorExpr(C)->getSourceRange();
5309
5310 if (clang_isStatement(C.kind))
5311 return getCursorStmt(C)->getSourceRange();
5312
5313 if (clang_isAttribute(C.kind))
5314 return getCursorAttr(C)->getRange();
5315
5316 if (C.kind == CXCursor_PreprocessingDirective)
5317 return cxcursor::getCursorPreprocessingDirective(C);
5318
5319 if (C.kind == CXCursor_MacroExpansion) {
5320 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005321 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005322 return TU->mapRangeFromPreamble(Range);
5323 }
5324
5325 if (C.kind == CXCursor_MacroDefinition) {
5326 ASTUnit *TU = getCursorASTUnit(C);
5327 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
5328 return TU->mapRangeFromPreamble(Range);
5329 }
5330
5331 if (C.kind == CXCursor_InclusionDirective) {
5332 ASTUnit *TU = getCursorASTUnit(C);
5333 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
5334 return TU->mapRangeFromPreamble(Range);
5335 }
5336
5337 if (C.kind == CXCursor_TranslationUnit) {
5338 ASTUnit *TU = getCursorASTUnit(C);
5339 FileID MainID = TU->getSourceManager().getMainFileID();
5340 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
5341 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
5342 return SourceRange(Start, End);
5343 }
5344
5345 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005346 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005347 if (!D)
5348 return SourceRange();
5349
5350 SourceRange R = D->getSourceRange();
5351 // FIXME: Multiple variables declared in a single declaration
5352 // currently lack the information needed to correctly determine their
5353 // ranges when accounting for the type-specifier. We use context
5354 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
5355 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005356 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005357 if (!cxcursor::isFirstInDeclGroup(C))
5358 R.setBegin(VD->getLocation());
5359 }
5360 return R;
5361 }
5362 return SourceRange();
5363}
5364
5365/// \brief Retrieves the "raw" cursor extent, which is then extended to include
5366/// the decl-specifier-seq for declarations.
5367static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
5368 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005369 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005370 if (!D)
5371 return SourceRange();
5372
5373 SourceRange R = D->getSourceRange();
5374
5375 // Adjust the start of the location for declarations preceded by
5376 // declaration specifiers.
5377 SourceLocation StartLoc;
5378 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
5379 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
5380 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005381 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005382 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
5383 StartLoc = TI->getTypeLoc().getLocStart();
5384 }
5385
5386 if (StartLoc.isValid() && R.getBegin().isValid() &&
5387 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
5388 R.setBegin(StartLoc);
5389
5390 // FIXME: Multiple variables declared in a single declaration
5391 // currently lack the information needed to correctly determine their
5392 // ranges when accounting for the type-specifier. We use context
5393 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
5394 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005395 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005396 if (!cxcursor::isFirstInDeclGroup(C))
5397 R.setBegin(VD->getLocation());
5398 }
5399
5400 return R;
5401 }
5402
5403 return getRawCursorExtent(C);
5404}
5405
5406extern "C" {
5407
5408CXSourceRange clang_getCursorExtent(CXCursor C) {
5409 SourceRange R = getRawCursorExtent(C);
5410 if (R.isInvalid())
5411 return clang_getNullRange();
5412
5413 return cxloc::translateSourceRange(getCursorContext(C), R);
5414}
5415
5416CXCursor clang_getCursorReferenced(CXCursor C) {
5417 if (clang_isInvalid(C.kind))
5418 return clang_getNullCursor();
5419
5420 CXTranslationUnit tu = getCursorTU(C);
5421 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005422 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005423 if (!D)
5424 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005425 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005426 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005427 if (const ObjCPropertyImplDecl *PropImpl =
5428 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005429 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
5430 return MakeCXCursor(Property, tu);
5431
5432 return C;
5433 }
5434
5435 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005436 const Expr *E = getCursorExpr(C);
5437 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00005438 if (D) {
5439 CXCursor declCursor = MakeCXCursor(D, tu);
5440 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
5441 declCursor);
5442 return declCursor;
5443 }
5444
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005445 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00005446 return MakeCursorOverloadedDeclRef(Ovl, tu);
5447
5448 return clang_getNullCursor();
5449 }
5450
5451 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005452 const Stmt *S = getCursorStmt(C);
5453 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00005454 if (LabelDecl *label = Goto->getLabel())
5455 if (LabelStmt *labelS = label->getStmt())
5456 return MakeCXCursor(labelS, getCursorDecl(C), tu);
5457
5458 return clang_getNullCursor();
5459 }
Richard Smith66a81862015-05-04 02:25:31 +00005460
Guy Benyei11169dd2012-12-18 14:30:41 +00005461 if (C.kind == CXCursor_MacroExpansion) {
Richard Smith66a81862015-05-04 02:25:31 +00005462 if (const MacroDefinitionRecord *Def =
5463 getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005464 return MakeMacroDefinitionCursor(Def, tu);
5465 }
5466
5467 if (!clang_isReference(C.kind))
5468 return clang_getNullCursor();
5469
5470 switch (C.kind) {
5471 case CXCursor_ObjCSuperClassRef:
5472 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
5473
5474 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005475 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
5476 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005477 return MakeCXCursor(Def, tu);
5478
5479 return MakeCXCursor(Prot, tu);
5480 }
5481
5482 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005483 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
5484 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005485 return MakeCXCursor(Def, tu);
5486
5487 return MakeCXCursor(Class, tu);
5488 }
5489
5490 case CXCursor_TypeRef:
5491 return MakeCXCursor(getCursorTypeRef(C).first, tu );
5492
5493 case CXCursor_TemplateRef:
5494 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
5495
5496 case CXCursor_NamespaceRef:
5497 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
5498
5499 case CXCursor_MemberRef:
5500 return MakeCXCursor(getCursorMemberRef(C).first, tu );
5501
5502 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005503 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005504 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
5505 tu ));
5506 }
5507
5508 case CXCursor_LabelRef:
5509 // FIXME: We end up faking the "parent" declaration here because we
5510 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005511 return MakeCXCursor(getCursorLabelRef(C).first,
5512 cxtu::getASTUnit(tu)->getASTContext()
5513 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00005514 tu);
5515
5516 case CXCursor_OverloadedDeclRef:
5517 return C;
5518
5519 case CXCursor_VariableRef:
5520 return MakeCXCursor(getCursorVariableRef(C).first, tu);
5521
5522 default:
5523 // We would prefer to enumerate all non-reference cursor kinds here.
5524 llvm_unreachable("Unhandled reference cursor kind");
5525 }
5526}
5527
5528CXCursor clang_getCursorDefinition(CXCursor C) {
5529 if (clang_isInvalid(C.kind))
5530 return clang_getNullCursor();
5531
5532 CXTranslationUnit TU = getCursorTU(C);
5533
5534 bool WasReference = false;
5535 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
5536 C = clang_getCursorReferenced(C);
5537 WasReference = true;
5538 }
5539
5540 if (C.kind == CXCursor_MacroExpansion)
5541 return clang_getCursorReferenced(C);
5542
5543 if (!clang_isDeclaration(C.kind))
5544 return clang_getNullCursor();
5545
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005546 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005547 if (!D)
5548 return clang_getNullCursor();
5549
5550 switch (D->getKind()) {
5551 // Declaration kinds that don't really separate the notions of
5552 // declaration and definition.
5553 case Decl::Namespace:
5554 case Decl::Typedef:
5555 case Decl::TypeAlias:
5556 case Decl::TypeAliasTemplate:
5557 case Decl::TemplateTypeParm:
5558 case Decl::EnumConstant:
5559 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00005560 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005561 case Decl::IndirectField:
5562 case Decl::ObjCIvar:
5563 case Decl::ObjCAtDefsField:
5564 case Decl::ImplicitParam:
5565 case Decl::ParmVar:
5566 case Decl::NonTypeTemplateParm:
5567 case Decl::TemplateTemplateParm:
5568 case Decl::ObjCCategoryImpl:
5569 case Decl::ObjCImplementation:
5570 case Decl::AccessSpec:
5571 case Decl::LinkageSpec:
5572 case Decl::ObjCPropertyImpl:
5573 case Decl::FileScopeAsm:
5574 case Decl::StaticAssert:
5575 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00005576 case Decl::Captured:
Alexey Bataev4244be22016-02-11 05:35:55 +00005577 case Decl::OMPCapturedExpr:
Guy Benyei11169dd2012-12-18 14:30:41 +00005578 case Decl::Label: // FIXME: Is this right??
5579 case Decl::ClassScopeFunctionSpecialization:
5580 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00005581 case Decl::OMPThreadPrivate:
Douglas Gregor85f3f952015-07-07 03:57:15 +00005582 case Decl::ObjCTypeParam:
David Majnemerd9b1a4f2015-11-04 03:40:30 +00005583 case Decl::BuiltinTemplate:
Guy Benyei11169dd2012-12-18 14:30:41 +00005584 return C;
5585
5586 // Declaration kinds that don't make any sense here, but are
5587 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00005588 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005589 case Decl::TranslationUnit:
Richard Smithf19e1272015-03-07 00:04:49 +00005590 case Decl::ExternCContext:
Guy Benyei11169dd2012-12-18 14:30:41 +00005591 break;
5592
5593 // Declaration kinds for which the definition is not resolvable.
5594 case Decl::UnresolvedUsingTypename:
5595 case Decl::UnresolvedUsingValue:
5596 break;
5597
5598 case Decl::UsingDirective:
5599 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
5600 TU);
5601
5602 case Decl::NamespaceAlias:
5603 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
5604
5605 case Decl::Enum:
5606 case Decl::Record:
5607 case Decl::CXXRecord:
5608 case Decl::ClassTemplateSpecialization:
5609 case Decl::ClassTemplatePartialSpecialization:
5610 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
5611 return MakeCXCursor(Def, TU);
5612 return clang_getNullCursor();
5613
5614 case Decl::Function:
5615 case Decl::CXXMethod:
5616 case Decl::CXXConstructor:
5617 case Decl::CXXDestructor:
5618 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00005619 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005620 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00005621 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005622 return clang_getNullCursor();
5623 }
5624
Larisse Voufo39a1e502013-08-06 01:03:05 +00005625 case Decl::Var:
5626 case Decl::VarTemplateSpecialization:
5627 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00005628 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005629 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005630 return MakeCXCursor(Def, TU);
5631 return clang_getNullCursor();
5632 }
5633
5634 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00005635 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005636 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
5637 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
5638 return clang_getNullCursor();
5639 }
5640
5641 case Decl::ClassTemplate: {
5642 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
5643 ->getDefinition())
5644 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
5645 TU);
5646 return clang_getNullCursor();
5647 }
5648
Larisse Voufo39a1e502013-08-06 01:03:05 +00005649 case Decl::VarTemplate: {
5650 if (VarDecl *Def =
5651 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
5652 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
5653 return clang_getNullCursor();
5654 }
5655
Guy Benyei11169dd2012-12-18 14:30:41 +00005656 case Decl::Using:
5657 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
5658 D->getLocation(), TU);
5659
5660 case Decl::UsingShadow:
5661 return clang_getCursorDefinition(
5662 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
5663 TU));
5664
5665 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005666 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005667 if (Method->isThisDeclarationADefinition())
5668 return C;
5669
5670 // Dig out the method definition in the associated
5671 // @implementation, if we have it.
5672 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005673 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005674 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
5675 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
5676 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
5677 Method->isInstanceMethod()))
5678 if (Def->isThisDeclarationADefinition())
5679 return MakeCXCursor(Def, TU);
5680
5681 return clang_getNullCursor();
5682 }
5683
5684 case Decl::ObjCCategory:
5685 if (ObjCCategoryImplDecl *Impl
5686 = cast<ObjCCategoryDecl>(D)->getImplementation())
5687 return MakeCXCursor(Impl, TU);
5688 return clang_getNullCursor();
5689
5690 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005691 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005692 return MakeCXCursor(Def, TU);
5693 return clang_getNullCursor();
5694
5695 case Decl::ObjCInterface: {
5696 // There are two notions of a "definition" for an Objective-C
5697 // class: the interface and its implementation. When we resolved a
5698 // reference to an Objective-C class, produce the @interface as
5699 // the definition; when we were provided with the interface,
5700 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005701 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005702 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005703 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005704 return MakeCXCursor(Def, TU);
5705 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
5706 return MakeCXCursor(Impl, TU);
5707 return clang_getNullCursor();
5708 }
5709
5710 case Decl::ObjCProperty:
5711 // FIXME: We don't really know where to find the
5712 // ObjCPropertyImplDecls that implement this property.
5713 return clang_getNullCursor();
5714
5715 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005716 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005717 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005718 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005719 return MakeCXCursor(Def, TU);
5720
5721 return clang_getNullCursor();
5722
5723 case Decl::Friend:
5724 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
5725 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5726 return clang_getNullCursor();
5727
5728 case Decl::FriendTemplate:
5729 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
5730 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5731 return clang_getNullCursor();
5732 }
5733
5734 return clang_getNullCursor();
5735}
5736
5737unsigned clang_isCursorDefinition(CXCursor C) {
5738 if (!clang_isDeclaration(C.kind))
5739 return 0;
5740
5741 return clang_getCursorDefinition(C) == C;
5742}
5743
5744CXCursor clang_getCanonicalCursor(CXCursor C) {
5745 if (!clang_isDeclaration(C.kind))
5746 return C;
5747
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005748 if (const Decl *D = getCursorDecl(C)) {
5749 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005750 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5751 return MakeCXCursor(CatD, getCursorTU(C));
5752
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005753 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5754 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00005755 return MakeCXCursor(IFD, getCursorTU(C));
5756
5757 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5758 }
5759
5760 return C;
5761}
5762
5763int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5764 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5765}
5766
5767unsigned clang_getNumOverloadedDecls(CXCursor C) {
5768 if (C.kind != CXCursor_OverloadedDeclRef)
5769 return 0;
5770
5771 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005772 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005773 return E->getNumDecls();
5774
5775 if (OverloadedTemplateStorage *S
5776 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5777 return S->size();
5778
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005779 const Decl *D = Storage.get<const Decl *>();
5780 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005781 return Using->shadow_size();
5782
5783 return 0;
5784}
5785
5786CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5787 if (cursor.kind != CXCursor_OverloadedDeclRef)
5788 return clang_getNullCursor();
5789
5790 if (index >= clang_getNumOverloadedDecls(cursor))
5791 return clang_getNullCursor();
5792
5793 CXTranslationUnit TU = getCursorTU(cursor);
5794 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005795 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005796 return MakeCXCursor(E->decls_begin()[index], TU);
5797
5798 if (OverloadedTemplateStorage *S
5799 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5800 return MakeCXCursor(S->begin()[index], TU);
5801
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005802 const Decl *D = Storage.get<const Decl *>();
5803 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005804 // FIXME: This is, unfortunately, linear time.
5805 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5806 std::advance(Pos, index);
5807 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5808 }
5809
5810 return clang_getNullCursor();
5811}
5812
5813void clang_getDefinitionSpellingAndExtent(CXCursor C,
5814 const char **startBuf,
5815 const char **endBuf,
5816 unsigned *startLine,
5817 unsigned *startColumn,
5818 unsigned *endLine,
5819 unsigned *endColumn) {
5820 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005821 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005822 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5823
5824 SourceManager &SM = FD->getASTContext().getSourceManager();
5825 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5826 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5827 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5828 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5829 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5830 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5831}
5832
5833
5834CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5835 unsigned PieceIndex) {
5836 RefNamePieces Pieces;
5837
5838 switch (C.kind) {
5839 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005840 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005841 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5842 E->getQualifierLoc().getSourceRange());
5843 break;
5844
5845 case CXCursor_DeclRefExpr:
James Y Knight04ec5bf2015-12-24 02:59:37 +00005846 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C))) {
5847 SourceRange TemplateArgLoc(E->getLAngleLoc(), E->getRAngleLoc());
5848 Pieces =
5849 buildPieces(NameFlags, false, E->getNameInfo(),
5850 E->getQualifierLoc().getSourceRange(), &TemplateArgLoc);
5851 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005852 break;
5853
5854 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005855 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005856 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005857 const Expr *Callee = OCE->getCallee();
5858 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005859 Callee = ICE->getSubExpr();
5860
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005861 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005862 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5863 DRE->getQualifierLoc().getSourceRange());
5864 }
5865 break;
5866
5867 default:
5868 break;
5869 }
5870
5871 if (Pieces.empty()) {
5872 if (PieceIndex == 0)
5873 return clang_getCursorExtent(C);
5874 } else if (PieceIndex < Pieces.size()) {
5875 SourceRange R = Pieces[PieceIndex];
5876 if (R.isValid())
5877 return cxloc::translateSourceRange(getCursorContext(C), R);
5878 }
5879
5880 return clang_getNullRange();
5881}
5882
5883void clang_enableStackTraces(void) {
5884 llvm::sys::PrintStackTraceOnErrorSignal();
5885}
5886
5887void clang_executeOnThread(void (*fn)(void*), void *user_data,
5888 unsigned stack_size) {
5889 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5890}
5891
5892} // end: extern "C"
5893
5894//===----------------------------------------------------------------------===//
5895// Token-based Operations.
5896//===----------------------------------------------------------------------===//
5897
5898/* CXToken layout:
5899 * int_data[0]: a CXTokenKind
5900 * int_data[1]: starting token location
5901 * int_data[2]: token length
5902 * int_data[3]: reserved
5903 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5904 * otherwise unused.
5905 */
5906extern "C" {
5907
5908CXTokenKind clang_getTokenKind(CXToken CXTok) {
5909 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5910}
5911
5912CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5913 switch (clang_getTokenKind(CXTok)) {
5914 case CXToken_Identifier:
5915 case CXToken_Keyword:
5916 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005917 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005918 ->getNameStart());
5919
5920 case CXToken_Literal: {
5921 // We have stashed the starting pointer in the ptr_data field. Use it.
5922 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005923 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005924 }
5925
5926 case CXToken_Punctuation:
5927 case CXToken_Comment:
5928 break;
5929 }
5930
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005931 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005932 LOG_BAD_TU(TU);
5933 return cxstring::createEmpty();
5934 }
5935
Guy Benyei11169dd2012-12-18 14:30:41 +00005936 // We have to find the starting buffer pointer the hard way, by
5937 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005938 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005939 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005940 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005941
5942 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5943 std::pair<FileID, unsigned> LocInfo
5944 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5945 bool Invalid = false;
5946 StringRef Buffer
5947 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5948 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005949 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005950
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005951 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005952}
5953
5954CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005955 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005956 LOG_BAD_TU(TU);
5957 return clang_getNullLocation();
5958 }
5959
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005960 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005961 if (!CXXUnit)
5962 return clang_getNullLocation();
5963
5964 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5965 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5966}
5967
5968CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005969 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005970 LOG_BAD_TU(TU);
5971 return clang_getNullRange();
5972 }
5973
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005974 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005975 if (!CXXUnit)
5976 return clang_getNullRange();
5977
5978 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5979 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5980}
5981
5982static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5983 SmallVectorImpl<CXToken> &CXTokens) {
5984 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5985 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005986 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005987 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005988 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005989
5990 // Cannot tokenize across files.
5991 if (BeginLocInfo.first != EndLocInfo.first)
5992 return;
5993
5994 // Create a lexer
5995 bool Invalid = false;
5996 StringRef Buffer
5997 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5998 if (Invalid)
5999 return;
6000
6001 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
6002 CXXUnit->getASTContext().getLangOpts(),
6003 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
6004 Lex.SetCommentRetentionState(true);
6005
6006 // Lex tokens until we hit the end of the range.
6007 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
6008 Token Tok;
6009 bool previousWasAt = false;
6010 do {
6011 // Lex the next token
6012 Lex.LexFromRawLexer(Tok);
6013 if (Tok.is(tok::eof))
6014 break;
6015
6016 // Initialize the CXToken.
6017 CXToken CXTok;
6018
6019 // - Common fields
6020 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
6021 CXTok.int_data[2] = Tok.getLength();
6022 CXTok.int_data[3] = 0;
6023
6024 // - Kind-specific fields
6025 if (Tok.isLiteral()) {
6026 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006027 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00006028 } else if (Tok.is(tok::raw_identifier)) {
6029 // Lookup the identifier to determine whether we have a keyword.
6030 IdentifierInfo *II
6031 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
6032
6033 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
6034 CXTok.int_data[0] = CXToken_Keyword;
6035 }
6036 else {
6037 CXTok.int_data[0] = Tok.is(tok::identifier)
6038 ? CXToken_Identifier
6039 : CXToken_Keyword;
6040 }
6041 CXTok.ptr_data = II;
6042 } else if (Tok.is(tok::comment)) {
6043 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00006044 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006045 } else {
6046 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00006047 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006048 }
6049 CXTokens.push_back(CXTok);
6050 previousWasAt = Tok.is(tok::at);
6051 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
6052}
6053
6054void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
6055 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006056 LOG_FUNC_SECTION {
6057 *Log << TU << ' ' << Range;
6058 }
6059
Guy Benyei11169dd2012-12-18 14:30:41 +00006060 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00006061 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006062 if (NumTokens)
6063 *NumTokens = 0;
6064
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006065 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006066 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00006067 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006068 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00006069
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006070 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006071 if (!CXXUnit || !Tokens || !NumTokens)
6072 return;
6073
6074 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
6075
6076 SourceRange R = cxloc::translateCXSourceRange(Range);
6077 if (R.isInvalid())
6078 return;
6079
6080 SmallVector<CXToken, 32> CXTokens;
6081 getTokens(CXXUnit, R, CXTokens);
6082
6083 if (CXTokens.empty())
6084 return;
6085
6086 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
6087 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
6088 *NumTokens = CXTokens.size();
6089}
6090
6091void clang_disposeTokens(CXTranslationUnit TU,
6092 CXToken *Tokens, unsigned NumTokens) {
6093 free(Tokens);
6094}
6095
6096} // end: extern "C"
6097
6098//===----------------------------------------------------------------------===//
6099// Token annotation APIs.
6100//===----------------------------------------------------------------------===//
6101
Guy Benyei11169dd2012-12-18 14:30:41 +00006102static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
6103 CXCursor parent,
6104 CXClientData client_data);
6105static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
6106 CXClientData client_data);
6107
6108namespace {
6109class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00006110 CXToken *Tokens;
6111 CXCursor *Cursors;
6112 unsigned NumTokens;
6113 unsigned TokIdx;
6114 unsigned PreprocessingTokIdx;
6115 CursorVisitor AnnotateVis;
6116 SourceManager &SrcMgr;
6117 bool HasContextSensitiveKeywords;
6118
6119 struct PostChildrenInfo {
6120 CXCursor Cursor;
6121 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006122 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006123 unsigned BeforeChildrenTokenIdx;
6124 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00006125 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006126
6127 CXToken &getTok(unsigned Idx) {
6128 assert(Idx < NumTokens);
6129 return Tokens[Idx];
6130 }
6131 const CXToken &getTok(unsigned Idx) const {
6132 assert(Idx < NumTokens);
6133 return Tokens[Idx];
6134 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006135 bool MoreTokens() const { return TokIdx < NumTokens; }
6136 unsigned NextToken() const { return TokIdx; }
6137 void AdvanceToken() { ++TokIdx; }
6138 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006139 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006140 }
6141 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006142 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006143 }
6144 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006145 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006146 }
6147
6148 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006149 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00006150 SourceRange);
6151
6152public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006153 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006154 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006155 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00006156 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006157 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00006158 AnnotateTokensVisitor, this,
6159 /*VisitPreprocessorLast=*/true,
6160 /*VisitIncludedEntities=*/false,
6161 RegionOfInterest,
6162 /*VisitDeclsOnly=*/false,
6163 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006164 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00006165 HasContextSensitiveKeywords(false) { }
6166
6167 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
6168 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
6169 bool postVisitChildren(CXCursor cursor);
6170 void AnnotateTokens();
6171
6172 /// \brief Determine whether the annotator saw any cursors that have
6173 /// context-sensitive keywords.
6174 bool hasContextSensitiveKeywords() const {
6175 return HasContextSensitiveKeywords;
6176 }
6177
6178 ~AnnotateTokensWorker() {
6179 assert(PostChildrenInfos.empty());
6180 }
6181};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00006182}
Guy Benyei11169dd2012-12-18 14:30:41 +00006183
6184void AnnotateTokensWorker::AnnotateTokens() {
6185 // Walk the AST within the region of interest, annotating tokens
6186 // along the way.
6187 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006188}
Guy Benyei11169dd2012-12-18 14:30:41 +00006189
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006190static inline void updateCursorAnnotation(CXCursor &Cursor,
6191 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006192 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00006193 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006194 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00006195}
6196
6197/// \brief It annotates and advances tokens with a cursor until the comparison
6198//// between the cursor location and the source range is the same as
6199/// \arg compResult.
6200///
6201/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
6202/// Pass RangeOverlap to annotate tokens inside a range.
6203void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
6204 RangeComparisonResult compResult,
6205 SourceRange range) {
6206 while (MoreTokens()) {
6207 const unsigned I = NextToken();
6208 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006209 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
6210 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00006211
6212 SourceLocation TokLoc = GetTokenLoc(I);
6213 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006214 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00006215 AdvanceToken();
6216 continue;
6217 }
6218 break;
6219 }
6220}
6221
6222/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006223/// \returns true if it advanced beyond all macro tokens, false otherwise.
6224bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00006225 CXCursor updateC,
6226 RangeComparisonResult compResult,
6227 SourceRange range) {
6228 assert(MoreTokens());
6229 assert(isFunctionMacroToken(NextToken()) &&
6230 "Should be called only for macro arg tokens");
6231
6232 // This works differently than annotateAndAdvanceTokens; because expanded
6233 // macro arguments can have arbitrary translation-unit source order, we do not
6234 // advance the token index one by one until a token fails the range test.
6235 // We only advance once past all of the macro arg tokens if all of them
6236 // pass the range test. If one of them fails we keep the token index pointing
6237 // at the start of the macro arg tokens so that the failing token will be
6238 // annotated by a subsequent annotation try.
6239
6240 bool atLeastOneCompFail = false;
6241
6242 unsigned I = NextToken();
6243 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
6244 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
6245 if (TokLoc.isFileID())
6246 continue; // not macro arg token, it's parens or comma.
6247 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
6248 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
6249 Cursors[I] = updateC;
6250 } else
6251 atLeastOneCompFail = true;
6252 }
6253
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006254 if (atLeastOneCompFail)
6255 return false;
6256
6257 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
6258 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00006259}
6260
6261enum CXChildVisitResult
6262AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006263 SourceRange cursorRange = getRawCursorExtent(cursor);
6264 if (cursorRange.isInvalid())
6265 return CXChildVisit_Recurse;
6266
6267 if (!HasContextSensitiveKeywords) {
6268 // Objective-C properties can have context-sensitive keywords.
6269 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006270 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006271 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
6272 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
6273 }
6274 // Objective-C methods can have context-sensitive keywords.
6275 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
6276 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006277 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00006278 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
6279 if (Method->getObjCDeclQualifier())
6280 HasContextSensitiveKeywords = true;
6281 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00006282 for (const auto *P : Method->params()) {
6283 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006284 HasContextSensitiveKeywords = true;
6285 break;
6286 }
6287 }
6288 }
6289 }
6290 }
6291 // C++ methods can have context-sensitive keywords.
6292 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006293 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00006294 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
6295 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
6296 HasContextSensitiveKeywords = true;
6297 }
6298 }
6299 // C++ classes can have context-sensitive keywords.
6300 else if (cursor.kind == CXCursor_StructDecl ||
6301 cursor.kind == CXCursor_ClassDecl ||
6302 cursor.kind == CXCursor_ClassTemplate ||
6303 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006304 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006305 if (D->hasAttr<FinalAttr>())
6306 HasContextSensitiveKeywords = true;
6307 }
6308 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00006309
6310 // Don't override a property annotation with its getter/setter method.
6311 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
6312 parent.kind == CXCursor_ObjCPropertyDecl)
6313 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00006314
6315 if (clang_isPreprocessing(cursor.kind)) {
6316 // Items in the preprocessing record are kept separate from items in
6317 // declarations, so we keep a separate token index.
6318 unsigned SavedTokIdx = TokIdx;
6319 TokIdx = PreprocessingTokIdx;
6320
6321 // Skip tokens up until we catch up to the beginning of the preprocessing
6322 // entry.
6323 while (MoreTokens()) {
6324 const unsigned I = NextToken();
6325 SourceLocation TokLoc = GetTokenLoc(I);
6326 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
6327 case RangeBefore:
6328 AdvanceToken();
6329 continue;
6330 case RangeAfter:
6331 case RangeOverlap:
6332 break;
6333 }
6334 break;
6335 }
6336
6337 // Look at all of the tokens within this range.
6338 while (MoreTokens()) {
6339 const unsigned I = NextToken();
6340 SourceLocation TokLoc = GetTokenLoc(I);
6341 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
6342 case RangeBefore:
6343 llvm_unreachable("Infeasible");
6344 case RangeAfter:
6345 break;
6346 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006347 // For macro expansions, just note where the beginning of the macro
6348 // expansion occurs.
6349 if (cursor.kind == CXCursor_MacroExpansion) {
6350 if (TokLoc == cursorRange.getBegin())
6351 Cursors[I] = cursor;
6352 AdvanceToken();
6353 break;
6354 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006355 // We may have already annotated macro names inside macro definitions.
6356 if (Cursors[I].kind != CXCursor_MacroExpansion)
6357 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00006358 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00006359 continue;
6360 }
6361 break;
6362 }
6363
6364 // Save the preprocessing token index; restore the non-preprocessing
6365 // token index.
6366 PreprocessingTokIdx = TokIdx;
6367 TokIdx = SavedTokIdx;
6368 return CXChildVisit_Recurse;
6369 }
6370
6371 if (cursorRange.isInvalid())
6372 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006373
6374 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00006375 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006376 const enum CXCursorKind K = clang_getCursorKind(parent);
6377 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006378 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
6379 // Attributes are annotated out-of-order, skip tokens until we reach it.
6380 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00006381 ? clang_getNullCursor() : parent;
6382
6383 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
6384
6385 // Avoid having the cursor of an expression "overwrite" the annotation of the
6386 // variable declaration that it belongs to.
6387 // This can happen for C++ constructor expressions whose range generally
6388 // include the variable declaration, e.g.:
6389 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006390 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00006391 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00006392 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006393 const unsigned I = NextToken();
6394 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
6395 E->getLocStart() == D->getLocation() &&
6396 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006397 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00006398 AdvanceToken();
6399 }
6400 }
6401 }
6402
6403 // Before recursing into the children keep some state that we are going
6404 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
6405 // extra work after the child nodes are visited.
6406 // Note that we don't call VisitChildren here to avoid traversing statements
6407 // code-recursively which can blow the stack.
6408
6409 PostChildrenInfo Info;
6410 Info.Cursor = cursor;
6411 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006412 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006413 Info.BeforeChildrenTokenIdx = NextToken();
6414 PostChildrenInfos.push_back(Info);
6415
6416 return CXChildVisit_Recurse;
6417}
6418
6419bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
6420 if (PostChildrenInfos.empty())
6421 return false;
6422 const PostChildrenInfo &Info = PostChildrenInfos.back();
6423 if (!clang_equalCursors(Info.Cursor, cursor))
6424 return false;
6425
6426 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
6427 const unsigned AfterChildren = NextToken();
6428 SourceRange cursorRange = Info.CursorRange;
6429
6430 // Scan the tokens that are at the end of the cursor, but are not captured
6431 // but the child cursors.
6432 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
6433
6434 // Scan the tokens that are at the beginning of the cursor, but are not
6435 // capture by the child cursors.
6436 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
6437 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
6438 break;
6439
6440 Cursors[I] = cursor;
6441 }
6442
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006443 // Attributes are annotated out-of-order, rewind TokIdx to when we first
6444 // encountered the attribute cursor.
6445 if (clang_isAttribute(cursor.kind))
6446 TokIdx = Info.BeforeReachingCursorIdx;
6447
Guy Benyei11169dd2012-12-18 14:30:41 +00006448 PostChildrenInfos.pop_back();
6449 return false;
6450}
6451
6452static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
6453 CXCursor parent,
6454 CXClientData client_data) {
6455 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
6456}
6457
6458static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
6459 CXClientData client_data) {
6460 return static_cast<AnnotateTokensWorker*>(client_data)->
6461 postVisitChildren(cursor);
6462}
6463
6464namespace {
6465
6466/// \brief Uses the macro expansions in the preprocessing record to find
6467/// and mark tokens that are macro arguments. This info is used by the
6468/// AnnotateTokensWorker.
6469class MarkMacroArgTokensVisitor {
6470 SourceManager &SM;
6471 CXToken *Tokens;
6472 unsigned NumTokens;
6473 unsigned CurIdx;
6474
6475public:
6476 MarkMacroArgTokensVisitor(SourceManager &SM,
6477 CXToken *tokens, unsigned numTokens)
6478 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
6479
6480 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
6481 if (cursor.kind != CXCursor_MacroExpansion)
6482 return CXChildVisit_Continue;
6483
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006484 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00006485 if (macroRange.getBegin() == macroRange.getEnd())
6486 return CXChildVisit_Continue; // it's not a function macro.
6487
6488 for (; CurIdx < NumTokens; ++CurIdx) {
6489 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
6490 macroRange.getBegin()))
6491 break;
6492 }
6493
6494 if (CurIdx == NumTokens)
6495 return CXChildVisit_Break;
6496
6497 for (; CurIdx < NumTokens; ++CurIdx) {
6498 SourceLocation tokLoc = getTokenLoc(CurIdx);
6499 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
6500 break;
6501
6502 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
6503 }
6504
6505 if (CurIdx == NumTokens)
6506 return CXChildVisit_Break;
6507
6508 return CXChildVisit_Continue;
6509 }
6510
6511private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006512 CXToken &getTok(unsigned Idx) {
6513 assert(Idx < NumTokens);
6514 return Tokens[Idx];
6515 }
6516 const CXToken &getTok(unsigned Idx) const {
6517 assert(Idx < NumTokens);
6518 return Tokens[Idx];
6519 }
6520
Guy Benyei11169dd2012-12-18 14:30:41 +00006521 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006522 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006523 }
6524
6525 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
6526 // The third field is reserved and currently not used. Use it here
6527 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006528 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00006529 }
6530};
6531
6532} // end anonymous namespace
6533
6534static CXChildVisitResult
6535MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
6536 CXClientData client_data) {
6537 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
6538 parent);
6539}
6540
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006541/// \brief Used by \c annotatePreprocessorTokens.
6542/// \returns true if lexing was finished, false otherwise.
6543static bool lexNext(Lexer &Lex, Token &Tok,
6544 unsigned &NextIdx, unsigned NumTokens) {
6545 if (NextIdx >= NumTokens)
6546 return true;
6547
6548 ++NextIdx;
6549 Lex.LexFromRawLexer(Tok);
Alexander Kornienko1a9f1842015-12-28 15:24:08 +00006550 return Tok.is(tok::eof);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006551}
6552
Guy Benyei11169dd2012-12-18 14:30:41 +00006553static void annotatePreprocessorTokens(CXTranslationUnit TU,
6554 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006555 CXCursor *Cursors,
6556 CXToken *Tokens,
6557 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006558 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006559
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006560 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00006561 SourceManager &SourceMgr = CXXUnit->getSourceManager();
6562 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006563 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00006564 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006565 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00006566
6567 if (BeginLocInfo.first != EndLocInfo.first)
6568 return;
6569
6570 StringRef Buffer;
6571 bool Invalid = false;
6572 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
6573 if (Buffer.empty() || Invalid)
6574 return;
6575
6576 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
6577 CXXUnit->getASTContext().getLangOpts(),
6578 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
6579 Buffer.end());
6580 Lex.SetCommentRetentionState(true);
6581
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006582 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006583 // Lex tokens in raw mode until we hit the end of the range, to avoid
6584 // entering #includes or expanding macros.
6585 while (true) {
6586 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006587 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6588 break;
6589 unsigned TokIdx = NextIdx-1;
6590 assert(Tok.getLocation() ==
6591 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006592
6593 reprocess:
6594 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006595 // We have found a preprocessing directive. Annotate the tokens
6596 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00006597 //
6598 // FIXME: Some simple tests here could identify macro definitions and
6599 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006600
6601 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006602 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6603 break;
6604
Craig Topper69186e72014-06-08 08:38:04 +00006605 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00006606 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006607 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6608 break;
6609
6610 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00006611 IdentifierInfo &II =
6612 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006613 SourceLocation MappedTokLoc =
6614 CXXUnit->mapLocationToPreamble(Tok.getLocation());
6615 MI = getMacroInfo(II, MappedTokLoc, TU);
6616 }
6617 }
6618
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006619 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00006620 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006621 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
6622 finished = true;
6623 break;
6624 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006625 // If we are in a macro definition, check if the token was ever a
6626 // macro name and annotate it if that's the case.
6627 if (MI) {
6628 SourceLocation SaveLoc = Tok.getLocation();
6629 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
Richard Smith66a81862015-05-04 02:25:31 +00006630 MacroDefinitionRecord *MacroDef =
6631 checkForMacroInMacroDefinition(MI, Tok, TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006632 Tok.setLocation(SaveLoc);
6633 if (MacroDef)
Richard Smith66a81862015-05-04 02:25:31 +00006634 Cursors[NextIdx - 1] =
6635 MakeMacroExpansionCursor(MacroDef, Tok.getLocation(), TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006636 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006637 } while (!Tok.isAtStartOfLine());
6638
6639 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
6640 assert(TokIdx <= LastIdx);
6641 SourceLocation EndLoc =
6642 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
6643 CXCursor Cursor =
6644 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
6645
6646 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006647 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006648
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006649 if (finished)
6650 break;
6651 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00006652 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006653 }
6654}
6655
6656// This gets run a separate thread to avoid stack blowout.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006657static void clang_annotateTokensImpl(CXTranslationUnit TU, ASTUnit *CXXUnit,
6658 CXToken *Tokens, unsigned NumTokens,
6659 CXCursor *Cursors) {
Dmitri Gribenko183436e2013-01-26 21:49:50 +00006660 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006661 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
6662 setThreadBackgroundPriority();
6663
6664 // Determine the region of interest, which contains all of the tokens.
6665 SourceRange RegionOfInterest;
6666 RegionOfInterest.setBegin(
6667 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
6668 RegionOfInterest.setEnd(
6669 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
6670 Tokens[NumTokens-1])));
6671
Guy Benyei11169dd2012-12-18 14:30:41 +00006672 // Relex the tokens within the source range to look for preprocessing
6673 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006674 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006675
6676 // If begin location points inside a macro argument, set it to the expansion
6677 // location so we can have the full context when annotating semantically.
6678 {
6679 SourceManager &SM = CXXUnit->getSourceManager();
6680 SourceLocation Loc =
6681 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
6682 if (Loc.isMacroID())
6683 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
6684 }
6685
Guy Benyei11169dd2012-12-18 14:30:41 +00006686 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
6687 // Search and mark tokens that are macro argument expansions.
6688 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
6689 Tokens, NumTokens);
6690 CursorVisitor MacroArgMarker(TU,
6691 MarkMacroArgTokensVisitorDelegate, &Visitor,
6692 /*VisitPreprocessorLast=*/true,
6693 /*VisitIncludedEntities=*/false,
6694 RegionOfInterest);
6695 MacroArgMarker.visitPreprocessedEntitiesInRegion();
6696 }
6697
6698 // Annotate all of the source locations in the region of interest that map to
6699 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006700 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00006701
6702 // FIXME: We use a ridiculous stack size here because the data-recursion
6703 // algorithm uses a large stack frame than the non-data recursive version,
6704 // and AnnotationTokensWorker currently transforms the data-recursion
6705 // algorithm back into a traditional recursion by explicitly calling
6706 // VisitChildren(). We will need to remove this explicit recursive call.
6707 W.AnnotateTokens();
6708
6709 // If we ran into any entities that involve context-sensitive keywords,
6710 // take another pass through the tokens to mark them as such.
6711 if (W.hasContextSensitiveKeywords()) {
6712 for (unsigned I = 0; I != NumTokens; ++I) {
6713 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
6714 continue;
6715
6716 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
6717 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006718 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006719 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
6720 if (Property->getPropertyAttributesAsWritten() != 0 &&
6721 llvm::StringSwitch<bool>(II->getName())
6722 .Case("readonly", true)
6723 .Case("assign", true)
6724 .Case("unsafe_unretained", true)
6725 .Case("readwrite", true)
6726 .Case("retain", true)
6727 .Case("copy", true)
6728 .Case("nonatomic", true)
6729 .Case("atomic", true)
6730 .Case("getter", true)
6731 .Case("setter", true)
6732 .Case("strong", true)
6733 .Case("weak", true)
6734 .Default(false))
6735 Tokens[I].int_data[0] = CXToken_Keyword;
6736 }
6737 continue;
6738 }
6739
6740 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6741 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6742 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6743 if (llvm::StringSwitch<bool>(II->getName())
6744 .Case("in", true)
6745 .Case("out", true)
6746 .Case("inout", true)
6747 .Case("oneway", true)
6748 .Case("bycopy", true)
6749 .Case("byref", true)
6750 .Default(false))
6751 Tokens[I].int_data[0] = CXToken_Keyword;
6752 continue;
6753 }
6754
6755 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6756 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6757 Tokens[I].int_data[0] = CXToken_Keyword;
6758 continue;
6759 }
6760 }
6761 }
6762}
6763
6764extern "C" {
6765
6766void clang_annotateTokens(CXTranslationUnit TU,
6767 CXToken *Tokens, unsigned NumTokens,
6768 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006769 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006770 LOG_BAD_TU(TU);
6771 return;
6772 }
6773 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006774 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006775 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006776 }
6777
6778 LOG_FUNC_SECTION {
6779 *Log << TU << ' ';
6780 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6781 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6782 *Log << clang_getRange(bloc, eloc);
6783 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006784
6785 // Any token we don't specifically annotate will have a NULL cursor.
6786 CXCursor C = clang_getNullCursor();
6787 for (unsigned I = 0; I != NumTokens; ++I)
6788 Cursors[I] = C;
6789
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006790 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006791 if (!CXXUnit)
6792 return;
6793
6794 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006795
6796 auto AnnotateTokensImpl = [=]() {
6797 clang_annotateTokensImpl(TU, CXXUnit, Tokens, NumTokens, Cursors);
6798 };
Guy Benyei11169dd2012-12-18 14:30:41 +00006799 llvm::CrashRecoveryContext CRC;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006800 if (!RunSafely(CRC, AnnotateTokensImpl, GetSafetyThreadStackSize() * 2)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006801 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6802 }
6803}
6804
6805} // end: extern "C"
6806
6807//===----------------------------------------------------------------------===//
6808// Operations for querying linkage of a cursor.
6809//===----------------------------------------------------------------------===//
6810
6811extern "C" {
6812CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6813 if (!clang_isDeclaration(cursor.kind))
6814 return CXLinkage_Invalid;
6815
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006816 const Decl *D = cxcursor::getCursorDecl(cursor);
6817 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006818 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006819 case NoLinkage:
6820 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006821 case InternalLinkage: return CXLinkage_Internal;
6822 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6823 case ExternalLinkage: return CXLinkage_External;
6824 };
6825
6826 return CXLinkage_Invalid;
6827}
6828} // end: extern "C"
6829
6830//===----------------------------------------------------------------------===//
Ehsan Akhgari93697fa2015-11-23 19:56:46 +00006831// Operations for querying visibility of a cursor.
6832//===----------------------------------------------------------------------===//
6833
6834extern "C" {
6835CXVisibilityKind clang_getCursorVisibility(CXCursor cursor) {
6836 if (!clang_isDeclaration(cursor.kind))
6837 return CXVisibility_Invalid;
6838
6839 const Decl *D = cxcursor::getCursorDecl(cursor);
6840 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
6841 switch (ND->getVisibility()) {
6842 case HiddenVisibility: return CXVisibility_Hidden;
6843 case ProtectedVisibility: return CXVisibility_Protected;
6844 case DefaultVisibility: return CXVisibility_Default;
6845 };
6846
6847 return CXVisibility_Invalid;
6848}
6849} // end: extern "C"
6850
6851//===----------------------------------------------------------------------===//
Guy Benyei11169dd2012-12-18 14:30:41 +00006852// Operations for querying language of a cursor.
6853//===----------------------------------------------------------------------===//
6854
6855static CXLanguageKind getDeclLanguage(const Decl *D) {
6856 if (!D)
6857 return CXLanguage_C;
6858
6859 switch (D->getKind()) {
6860 default:
6861 break;
6862 case Decl::ImplicitParam:
6863 case Decl::ObjCAtDefsField:
6864 case Decl::ObjCCategory:
6865 case Decl::ObjCCategoryImpl:
6866 case Decl::ObjCCompatibleAlias:
6867 case Decl::ObjCImplementation:
6868 case Decl::ObjCInterface:
6869 case Decl::ObjCIvar:
6870 case Decl::ObjCMethod:
6871 case Decl::ObjCProperty:
6872 case Decl::ObjCPropertyImpl:
6873 case Decl::ObjCProtocol:
Douglas Gregor85f3f952015-07-07 03:57:15 +00006874 case Decl::ObjCTypeParam:
Guy Benyei11169dd2012-12-18 14:30:41 +00006875 return CXLanguage_ObjC;
6876 case Decl::CXXConstructor:
6877 case Decl::CXXConversion:
6878 case Decl::CXXDestructor:
6879 case Decl::CXXMethod:
6880 case Decl::CXXRecord:
6881 case Decl::ClassTemplate:
6882 case Decl::ClassTemplatePartialSpecialization:
6883 case Decl::ClassTemplateSpecialization:
6884 case Decl::Friend:
6885 case Decl::FriendTemplate:
6886 case Decl::FunctionTemplate:
6887 case Decl::LinkageSpec:
6888 case Decl::Namespace:
6889 case Decl::NamespaceAlias:
6890 case Decl::NonTypeTemplateParm:
6891 case Decl::StaticAssert:
6892 case Decl::TemplateTemplateParm:
6893 case Decl::TemplateTypeParm:
6894 case Decl::UnresolvedUsingTypename:
6895 case Decl::UnresolvedUsingValue:
6896 case Decl::Using:
6897 case Decl::UsingDirective:
6898 case Decl::UsingShadow:
6899 return CXLanguage_CPlusPlus;
6900 }
6901
6902 return CXLanguage_C;
6903}
6904
6905extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006906
6907static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6908 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
Manuel Klimek8e3a7ed2015-09-25 17:53:16 +00006909 return CXAvailability_NotAvailable;
Guy Benyei11169dd2012-12-18 14:30:41 +00006910
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006911 switch (D->getAvailability()) {
6912 case AR_Available:
6913 case AR_NotYetIntroduced:
6914 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006915 return getCursorAvailabilityForDecl(
6916 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006917 return CXAvailability_Available;
6918
6919 case AR_Deprecated:
6920 return CXAvailability_Deprecated;
6921
6922 case AR_Unavailable:
6923 return CXAvailability_NotAvailable;
6924 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006925
6926 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006927}
6928
Guy Benyei11169dd2012-12-18 14:30:41 +00006929enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6930 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006931 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6932 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006933
6934 return CXAvailability_Available;
6935}
6936
6937static CXVersion convertVersion(VersionTuple In) {
6938 CXVersion Out = { -1, -1, -1 };
6939 if (In.empty())
6940 return Out;
6941
6942 Out.Major = In.getMajor();
6943
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006944 Optional<unsigned> Minor = In.getMinor();
6945 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006946 Out.Minor = *Minor;
6947 else
6948 return Out;
6949
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006950 Optional<unsigned> Subminor = In.getSubminor();
6951 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006952 Out.Subminor = *Subminor;
6953
6954 return Out;
6955}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006956
6957static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6958 int *always_deprecated,
6959 CXString *deprecated_message,
6960 int *always_unavailable,
6961 CXString *unavailable_message,
6962 CXPlatformAvailability *availability,
6963 int availability_size) {
6964 bool HadAvailAttr = false;
6965 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006966 for (auto A : D->attrs()) {
6967 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006968 HadAvailAttr = true;
6969 if (always_deprecated)
6970 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006971 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006972 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006973 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006974 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006975 continue;
6976 }
6977
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006978 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006979 HadAvailAttr = true;
6980 if (always_unavailable)
6981 *always_unavailable = 1;
6982 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006983 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006984 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6985 }
6986 continue;
6987 }
6988
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006989 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006990 HadAvailAttr = true;
6991 if (N < availability_size) {
6992 availability[N].Platform
6993 = cxstring::createDup(Avail->getPlatform()->getName());
6994 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6995 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6996 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6997 availability[N].Unavailable = Avail->getUnavailable();
6998 availability[N].Message = cxstring::createDup(Avail->getMessage());
6999 }
7000 ++N;
7001 }
7002 }
7003
7004 if (!HadAvailAttr)
7005 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
7006 return getCursorPlatformAvailabilityForDecl(
7007 cast<Decl>(EnumConst->getDeclContext()),
7008 always_deprecated,
7009 deprecated_message,
7010 always_unavailable,
7011 unavailable_message,
7012 availability,
7013 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00007014
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007015 return N;
7016}
7017
Guy Benyei11169dd2012-12-18 14:30:41 +00007018int clang_getCursorPlatformAvailability(CXCursor cursor,
7019 int *always_deprecated,
7020 CXString *deprecated_message,
7021 int *always_unavailable,
7022 CXString *unavailable_message,
7023 CXPlatformAvailability *availability,
7024 int availability_size) {
7025 if (always_deprecated)
7026 *always_deprecated = 0;
7027 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007028 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00007029 if (always_unavailable)
7030 *always_unavailable = 0;
7031 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007032 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007033
Guy Benyei11169dd2012-12-18 14:30:41 +00007034 if (!clang_isDeclaration(cursor.kind))
7035 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007036
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007037 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00007038 if (!D)
7039 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007040
7041 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
7042 deprecated_message,
7043 always_unavailable,
7044 unavailable_message,
7045 availability,
7046 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00007047}
7048
7049void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
7050 clang_disposeString(availability->Platform);
7051 clang_disposeString(availability->Message);
7052}
7053
7054CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
7055 if (clang_isDeclaration(cursor.kind))
7056 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
7057
7058 return CXLanguage_Invalid;
7059}
7060
7061 /// \brief If the given cursor is the "templated" declaration
7062 /// descibing a class or function template, return the class or
7063 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007064static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007065 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00007066 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007067
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007068 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00007069 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
7070 return FunTmpl;
7071
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007072 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00007073 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
7074 return ClassTmpl;
7075
7076 return D;
7077}
7078
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00007079
7080enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
7081 StorageClass sc = SC_None;
7082 const Decl *D = getCursorDecl(C);
7083 if (D) {
7084 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
7085 sc = FD->getStorageClass();
7086 } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
7087 sc = VD->getStorageClass();
7088 } else {
7089 return CX_SC_Invalid;
7090 }
7091 } else {
7092 return CX_SC_Invalid;
7093 }
7094 switch (sc) {
7095 case SC_None:
7096 return CX_SC_None;
7097 case SC_Extern:
7098 return CX_SC_Extern;
7099 case SC_Static:
7100 return CX_SC_Static;
7101 case SC_PrivateExtern:
7102 return CX_SC_PrivateExtern;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00007103 case SC_Auto:
7104 return CX_SC_Auto;
7105 case SC_Register:
7106 return CX_SC_Register;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00007107 }
Kaelyn Takataab61e702014-10-15 18:03:26 +00007108 llvm_unreachable("Unhandled storage class!");
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00007109}
7110
Guy Benyei11169dd2012-12-18 14:30:41 +00007111CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
7112 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007113 if (const Decl *D = getCursorDecl(cursor)) {
7114 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00007115 if (!DC)
7116 return clang_getNullCursor();
7117
7118 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
7119 getCursorTU(cursor));
7120 }
7121 }
7122
7123 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007124 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00007125 return MakeCXCursor(D, getCursorTU(cursor));
7126 }
7127
7128 return clang_getNullCursor();
7129}
7130
7131CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
7132 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007133 if (const Decl *D = getCursorDecl(cursor)) {
7134 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00007135 if (!DC)
7136 return clang_getNullCursor();
7137
7138 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
7139 getCursorTU(cursor));
7140 }
7141 }
7142
7143 // FIXME: Note that we can't easily compute the lexical context of a
7144 // statement or expression, so we return nothing.
7145 return clang_getNullCursor();
7146}
7147
7148CXFile clang_getIncludedFile(CXCursor cursor) {
7149 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00007150 return nullptr;
7151
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007152 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00007153 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00007154}
7155
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00007156unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
7157 if (C.kind != CXCursor_ObjCPropertyDecl)
7158 return CXObjCPropertyAttr_noattr;
7159
7160 unsigned Result = CXObjCPropertyAttr_noattr;
7161 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
7162 ObjCPropertyDecl::PropertyAttributeKind Attr =
7163 PD->getPropertyAttributesAsWritten();
7164
7165#define SET_CXOBJCPROP_ATTR(A) \
7166 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
7167 Result |= CXObjCPropertyAttr_##A
7168 SET_CXOBJCPROP_ATTR(readonly);
7169 SET_CXOBJCPROP_ATTR(getter);
7170 SET_CXOBJCPROP_ATTR(assign);
7171 SET_CXOBJCPROP_ATTR(readwrite);
7172 SET_CXOBJCPROP_ATTR(retain);
7173 SET_CXOBJCPROP_ATTR(copy);
7174 SET_CXOBJCPROP_ATTR(nonatomic);
7175 SET_CXOBJCPROP_ATTR(setter);
7176 SET_CXOBJCPROP_ATTR(atomic);
7177 SET_CXOBJCPROP_ATTR(weak);
7178 SET_CXOBJCPROP_ATTR(strong);
7179 SET_CXOBJCPROP_ATTR(unsafe_unretained);
7180#undef SET_CXOBJCPROP_ATTR
7181
7182 return Result;
7183}
7184
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00007185unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
7186 if (!clang_isDeclaration(C.kind))
7187 return CXObjCDeclQualifier_None;
7188
7189 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
7190 const Decl *D = getCursorDecl(C);
7191 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
7192 QT = MD->getObjCDeclQualifier();
7193 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
7194 QT = PD->getObjCDeclQualifier();
7195 if (QT == Decl::OBJC_TQ_None)
7196 return CXObjCDeclQualifier_None;
7197
7198 unsigned Result = CXObjCDeclQualifier_None;
7199 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
7200 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
7201 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
7202 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
7203 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
7204 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
7205
7206 return Result;
7207}
7208
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00007209unsigned clang_Cursor_isObjCOptional(CXCursor C) {
7210 if (!clang_isDeclaration(C.kind))
7211 return 0;
7212
7213 const Decl *D = getCursorDecl(C);
7214 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
7215 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
7216 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
7217 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
7218
7219 return 0;
7220}
7221
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00007222unsigned clang_Cursor_isVariadic(CXCursor C) {
7223 if (!clang_isDeclaration(C.kind))
7224 return 0;
7225
7226 const Decl *D = getCursorDecl(C);
7227 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
7228 return FD->isVariadic();
7229 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
7230 return MD->isVariadic();
7231
7232 return 0;
7233}
7234
Guy Benyei11169dd2012-12-18 14:30:41 +00007235CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
7236 if (!clang_isDeclaration(C.kind))
7237 return clang_getNullRange();
7238
7239 const Decl *D = getCursorDecl(C);
7240 ASTContext &Context = getCursorContext(C);
7241 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
7242 if (!RC)
7243 return clang_getNullRange();
7244
7245 return cxloc::translateSourceRange(Context, RC->getSourceRange());
7246}
7247
7248CXString clang_Cursor_getRawCommentText(CXCursor C) {
7249 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00007250 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00007251
7252 const Decl *D = getCursorDecl(C);
7253 ASTContext &Context = getCursorContext(C);
7254 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
7255 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
7256 StringRef();
7257
7258 // Don't duplicate the string because RawText points directly into source
7259 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007260 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00007261}
7262
7263CXString clang_Cursor_getBriefCommentText(CXCursor C) {
7264 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00007265 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00007266
7267 const Decl *D = getCursorDecl(C);
7268 const ASTContext &Context = getCursorContext(C);
7269 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
7270
7271 if (RC) {
7272 StringRef BriefText = RC->getBriefText(Context);
7273
7274 // Don't duplicate the string because RawComment ensures that this memory
7275 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007276 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00007277 }
7278
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00007279 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00007280}
7281
Guy Benyei11169dd2012-12-18 14:30:41 +00007282CXModule clang_Cursor_getModule(CXCursor C) {
7283 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007284 if (const ImportDecl *ImportD =
7285 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00007286 return ImportD->getImportedModule();
7287 }
7288
Craig Topper69186e72014-06-08 08:38:04 +00007289 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007290}
7291
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00007292CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
7293 if (isNotUsableTU(TU)) {
7294 LOG_BAD_TU(TU);
7295 return nullptr;
7296 }
7297 if (!File)
7298 return nullptr;
7299 FileEntry *FE = static_cast<FileEntry *>(File);
7300
7301 ASTUnit &Unit = *cxtu::getASTUnit(TU);
7302 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
7303 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
7304
Richard Smithfeb54b62014-10-23 02:01:19 +00007305 return Header.getModule();
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00007306}
7307
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00007308CXFile clang_Module_getASTFile(CXModule CXMod) {
7309 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00007310 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00007311 Module *Mod = static_cast<Module*>(CXMod);
7312 return const_cast<FileEntry *>(Mod->getASTFile());
7313}
7314
Guy Benyei11169dd2012-12-18 14:30:41 +00007315CXModule clang_Module_getParent(CXModule CXMod) {
7316 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00007317 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007318 Module *Mod = static_cast<Module*>(CXMod);
7319 return Mod->Parent;
7320}
7321
7322CXString clang_Module_getName(CXModule CXMod) {
7323 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007324 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00007325 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007326 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00007327}
7328
7329CXString clang_Module_getFullName(CXModule CXMod) {
7330 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007331 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00007332 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007333 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00007334}
7335
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00007336int clang_Module_isSystem(CXModule CXMod) {
7337 if (!CXMod)
7338 return 0;
7339 Module *Mod = static_cast<Module*>(CXMod);
7340 return Mod->IsSystem;
7341}
7342
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007343unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
7344 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007345 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007346 LOG_BAD_TU(TU);
7347 return 0;
7348 }
7349 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00007350 return 0;
7351 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007352 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
7353 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
7354 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00007355}
7356
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007357CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
7358 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007359 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007360 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00007361 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007362 }
7363 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00007364 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007365 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007366 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00007367
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007368 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
7369 if (Index < TopHeaders.size())
7370 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00007371
Craig Topper69186e72014-06-08 08:38:04 +00007372 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007373}
7374
7375} // end: extern "C"
7376
7377//===----------------------------------------------------------------------===//
7378// C++ AST instrospection.
7379//===----------------------------------------------------------------------===//
7380
7381extern "C" {
Saleem Abdulrasool6ea75db2015-10-27 15:50:22 +00007382unsigned clang_CXXField_isMutable(CXCursor C) {
7383 if (!clang_isDeclaration(C.kind))
7384 return 0;
7385
7386 if (const auto D = cxcursor::getCursorDecl(C))
7387 if (const auto FD = dyn_cast_or_null<FieldDecl>(D))
7388 return FD->isMutable() ? 1 : 0;
7389 return 0;
7390}
7391
Dmitri Gribenko62770be2013-05-17 18:38:35 +00007392unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
7393 if (!clang_isDeclaration(C.kind))
7394 return 0;
7395
Dmitri Gribenko62770be2013-05-17 18:38:35 +00007396 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007397 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007398 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00007399 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
7400}
7401
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00007402unsigned clang_CXXMethod_isConst(CXCursor C) {
7403 if (!clang_isDeclaration(C.kind))
7404 return 0;
7405
7406 const Decl *D = cxcursor::getCursorDecl(C);
7407 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007408 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00007409 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
7410}
7411
Guy Benyei11169dd2012-12-18 14:30:41 +00007412unsigned clang_CXXMethod_isStatic(CXCursor C) {
7413 if (!clang_isDeclaration(C.kind))
7414 return 0;
7415
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007416 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007417 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007418 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007419 return (Method && Method->isStatic()) ? 1 : 0;
7420}
7421
7422unsigned clang_CXXMethod_isVirtual(CXCursor C) {
7423 if (!clang_isDeclaration(C.kind))
7424 return 0;
7425
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007426 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007427 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007428 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007429 return (Method && Method->isVirtual()) ? 1 : 0;
7430}
7431} // end: extern "C"
7432
7433//===----------------------------------------------------------------------===//
7434// Attribute introspection.
7435//===----------------------------------------------------------------------===//
7436
7437extern "C" {
7438CXType clang_getIBOutletCollectionType(CXCursor C) {
7439 if (C.kind != CXCursor_IBOutletCollectionAttr)
7440 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
7441
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00007442 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00007443 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
7444
7445 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
7446}
7447} // end: extern "C"
7448
7449//===----------------------------------------------------------------------===//
7450// Inspecting memory usage.
7451//===----------------------------------------------------------------------===//
7452
7453typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
7454
7455static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
7456 enum CXTUResourceUsageKind k,
7457 unsigned long amount) {
7458 CXTUResourceUsageEntry entry = { k, amount };
7459 entries.push_back(entry);
7460}
7461
7462extern "C" {
7463
7464const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
7465 const char *str = "";
7466 switch (kind) {
7467 case CXTUResourceUsage_AST:
7468 str = "ASTContext: expressions, declarations, and types";
7469 break;
7470 case CXTUResourceUsage_Identifiers:
7471 str = "ASTContext: identifiers";
7472 break;
7473 case CXTUResourceUsage_Selectors:
7474 str = "ASTContext: selectors";
7475 break;
7476 case CXTUResourceUsage_GlobalCompletionResults:
7477 str = "Code completion: cached global results";
7478 break;
7479 case CXTUResourceUsage_SourceManagerContentCache:
7480 str = "SourceManager: content cache allocator";
7481 break;
7482 case CXTUResourceUsage_AST_SideTables:
7483 str = "ASTContext: side tables";
7484 break;
7485 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
7486 str = "SourceManager: malloc'ed memory buffers";
7487 break;
7488 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
7489 str = "SourceManager: mmap'ed memory buffers";
7490 break;
7491 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
7492 str = "ExternalASTSource: malloc'ed memory buffers";
7493 break;
7494 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
7495 str = "ExternalASTSource: mmap'ed memory buffers";
7496 break;
7497 case CXTUResourceUsage_Preprocessor:
7498 str = "Preprocessor: malloc'ed memory";
7499 break;
7500 case CXTUResourceUsage_PreprocessingRecord:
7501 str = "Preprocessor: PreprocessingRecord";
7502 break;
7503 case CXTUResourceUsage_SourceManager_DataStructures:
7504 str = "SourceManager: data structures and tables";
7505 break;
7506 case CXTUResourceUsage_Preprocessor_HeaderSearch:
7507 str = "Preprocessor: header search tables";
7508 break;
7509 }
7510 return str;
7511}
7512
7513CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007514 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007515 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00007516 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00007517 return usage;
7518 }
7519
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007520 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00007521 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00007522 ASTContext &astContext = astUnit->getASTContext();
7523
7524 // How much memory is used by AST nodes and types?
7525 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
7526 (unsigned long) astContext.getASTAllocatedMemory());
7527
7528 // How much memory is used by identifiers?
7529 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
7530 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
7531
7532 // How much memory is used for selectors?
7533 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
7534 (unsigned long) astContext.Selectors.getTotalMemory());
7535
7536 // How much memory is used by ASTContext's side tables?
7537 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
7538 (unsigned long) astContext.getSideTableAllocatedMemory());
7539
7540 // How much memory is used for caching global code completion results?
7541 unsigned long completionBytes = 0;
7542 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00007543 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007544 completionBytes = completionAllocator->getTotalMemory();
7545 }
7546 createCXTUResourceUsageEntry(*entries,
7547 CXTUResourceUsage_GlobalCompletionResults,
7548 completionBytes);
7549
7550 // How much memory is being used by SourceManager's content cache?
7551 createCXTUResourceUsageEntry(*entries,
7552 CXTUResourceUsage_SourceManagerContentCache,
7553 (unsigned long) astContext.getSourceManager().getContentCacheSize());
7554
7555 // How much memory is being used by the MemoryBuffer's in SourceManager?
7556 const SourceManager::MemoryBufferSizes &srcBufs =
7557 astUnit->getSourceManager().getMemoryBufferSizes();
7558
7559 createCXTUResourceUsageEntry(*entries,
7560 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
7561 (unsigned long) srcBufs.malloc_bytes);
7562 createCXTUResourceUsageEntry(*entries,
7563 CXTUResourceUsage_SourceManager_Membuffer_MMap,
7564 (unsigned long) srcBufs.mmap_bytes);
7565 createCXTUResourceUsageEntry(*entries,
7566 CXTUResourceUsage_SourceManager_DataStructures,
7567 (unsigned long) astContext.getSourceManager()
7568 .getDataStructureSizes());
7569
7570 // How much memory is being used by the ExternalASTSource?
7571 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
7572 const ExternalASTSource::MemoryBufferSizes &sizes =
7573 esrc->getMemoryBufferSizes();
7574
7575 createCXTUResourceUsageEntry(*entries,
7576 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
7577 (unsigned long) sizes.malloc_bytes);
7578 createCXTUResourceUsageEntry(*entries,
7579 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
7580 (unsigned long) sizes.mmap_bytes);
7581 }
7582
7583 // How much memory is being used by the Preprocessor?
7584 Preprocessor &pp = astUnit->getPreprocessor();
7585 createCXTUResourceUsageEntry(*entries,
7586 CXTUResourceUsage_Preprocessor,
7587 pp.getTotalMemory());
7588
7589 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
7590 createCXTUResourceUsageEntry(*entries,
7591 CXTUResourceUsage_PreprocessingRecord,
7592 pRec->getTotalMemory());
7593 }
7594
7595 createCXTUResourceUsageEntry(*entries,
7596 CXTUResourceUsage_Preprocessor_HeaderSearch,
7597 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00007598
Guy Benyei11169dd2012-12-18 14:30:41 +00007599 CXTUResourceUsage usage = { (void*) entries.get(),
7600 (unsigned) entries->size(),
Alexander Kornienko6ee521c2015-01-23 15:36:10 +00007601 !entries->empty() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00007602 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00007603 return usage;
7604}
7605
7606void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
7607 if (usage.data)
7608 delete (MemUsageEntries*) usage.data;
7609}
7610
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007611CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
7612 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007613 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00007614 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007615
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007616 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007617 LOG_BAD_TU(TU);
7618 return skipped;
7619 }
7620
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007621 if (!file)
7622 return skipped;
7623
7624 ASTUnit *astUnit = cxtu::getASTUnit(TU);
7625 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
7626 if (!ppRec)
7627 return skipped;
7628
7629 ASTContext &Ctx = astUnit->getASTContext();
7630 SourceManager &sm = Ctx.getSourceManager();
7631 FileEntry *fileEntry = static_cast<FileEntry *>(file);
7632 FileID wantedFileID = sm.translateFile(fileEntry);
7633
7634 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
7635 std::vector<SourceRange> wantedRanges;
7636 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
7637 i != ei; ++i) {
7638 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
7639 wantedRanges.push_back(*i);
7640 }
7641
7642 skipped->count = wantedRanges.size();
7643 skipped->ranges = new CXSourceRange[skipped->count];
7644 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
7645 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
7646
7647 return skipped;
7648}
7649
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007650void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
7651 if (ranges) {
7652 delete[] ranges->ranges;
7653 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007654 }
7655}
7656
Guy Benyei11169dd2012-12-18 14:30:41 +00007657} // end extern "C"
7658
7659void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
7660 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
7661 for (unsigned I = 0; I != Usage.numEntries; ++I)
7662 fprintf(stderr, " %s: %lu\n",
7663 clang_getTUResourceUsageName(Usage.entries[I].kind),
7664 Usage.entries[I].amount);
7665
7666 clang_disposeCXTUResourceUsage(Usage);
7667}
7668
7669//===----------------------------------------------------------------------===//
7670// Misc. utility functions.
7671//===----------------------------------------------------------------------===//
7672
7673/// Default to using an 8 MB stack size on "safety" threads.
7674static unsigned SafetyStackThreadSize = 8 << 20;
7675
7676namespace clang {
7677
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007678bool RunSafely(llvm::CrashRecoveryContext &CRC, llvm::function_ref<void()> Fn,
Guy Benyei11169dd2012-12-18 14:30:41 +00007679 unsigned Size) {
7680 if (!Size)
7681 Size = GetSafetyThreadStackSize();
7682 if (Size)
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007683 return CRC.RunSafelyOnThread(Fn, Size);
7684 return CRC.RunSafely(Fn);
Guy Benyei11169dd2012-12-18 14:30:41 +00007685}
7686
7687unsigned GetSafetyThreadStackSize() {
7688 return SafetyStackThreadSize;
7689}
7690
7691void SetSafetyThreadStackSize(unsigned Value) {
7692 SafetyStackThreadSize = Value;
7693}
7694
Alexander Kornienkoab9db512015-06-22 23:07:51 +00007695}
Guy Benyei11169dd2012-12-18 14:30:41 +00007696
7697void clang::setThreadBackgroundPriority() {
7698 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
7699 return;
7700
Alp Toker1a86ad22014-07-06 06:24:00 +00007701#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00007702 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
7703#endif
7704}
7705
7706void cxindex::printDiagsToStderr(ASTUnit *Unit) {
7707 if (!Unit)
7708 return;
7709
7710 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
7711 DEnd = Unit->stored_diag_end();
7712 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00007713 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00007714 CXString Msg = clang_formatDiagnostic(&Diag,
7715 clang_defaultDiagnosticDisplayOptions());
7716 fprintf(stderr, "%s\n", clang_getCString(Msg));
7717 clang_disposeString(Msg);
7718 }
7719#ifdef LLVM_ON_WIN32
7720 // On Windows, force a flush, since there may be multiple copies of
7721 // stderr and stdout in the file system, all with different buffers
7722 // but writing to the same device.
7723 fflush(stderr);
7724#endif
7725}
7726
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007727MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
7728 SourceLocation MacroDefLoc,
7729 CXTranslationUnit TU){
7730 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007731 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007732 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007733 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007734
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007735 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007736 Preprocessor &PP = Unit->getPreprocessor();
Richard Smith20e883e2015-04-29 23:20:19 +00007737 MacroDirective *MD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007738 if (MD) {
7739 for (MacroDirective::DefInfo
7740 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
7741 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
7742 return Def.getMacroInfo();
7743 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007744 }
7745
Craig Topper69186e72014-06-08 08:38:04 +00007746 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007747}
7748
Richard Smith66a81862015-05-04 02:25:31 +00007749const MacroInfo *cxindex::getMacroInfo(const MacroDefinitionRecord *MacroDef,
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007750 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007751 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007752 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007753 const IdentifierInfo *II = MacroDef->getName();
7754 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00007755 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007756
7757 return getMacroInfo(*II, MacroDef->getLocation(), TU);
7758}
7759
Richard Smith66a81862015-05-04 02:25:31 +00007760MacroDefinitionRecord *
7761cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, const Token &Tok,
7762 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007763 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007764 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007765 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00007766 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007767
7768 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007769 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007770 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
7771 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007772 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007773
7774 // Check that the token is inside the definition and not its argument list.
7775 SourceManager &SM = Unit->getSourceManager();
7776 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00007777 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007778 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00007779 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007780
7781 Preprocessor &PP = Unit->getPreprocessor();
7782 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
7783 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00007784 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007785
Alp Toker2d57cea2014-05-17 04:53:25 +00007786 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007787 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007788 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007789
7790 // Check that the identifier is not one of the macro arguments.
7791 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00007792 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007793
Richard Smith20e883e2015-04-29 23:20:19 +00007794 MacroDirective *InnerMD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007795 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00007796 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007797
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007798 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007799}
7800
Richard Smith66a81862015-05-04 02:25:31 +00007801MacroDefinitionRecord *
7802cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, SourceLocation Loc,
7803 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007804 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007805 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007806
7807 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007808 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007809 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007810 Preprocessor &PP = Unit->getPreprocessor();
7811 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00007812 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007813 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7814 Token Tok;
7815 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00007816 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007817
7818 return checkForMacroInMacroDefinition(MI, Tok, TU);
7819}
7820
Guy Benyei11169dd2012-12-18 14:30:41 +00007821extern "C" {
7822
7823CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007824 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00007825}
7826
7827} // end: extern "C"
7828
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007829Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7830 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007831 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007832 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007833 if (Unit->isMainFileAST())
7834 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007835 return *this;
7836 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007837 } else {
7838 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007839 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007840 return *this;
7841}
7842
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007843Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7844 *this << FE->getName();
7845 return *this;
7846}
7847
7848Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7849 CXString cursorName = clang_getCursorDisplayName(cursor);
7850 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7851 clang_disposeString(cursorName);
7852 return *this;
7853}
7854
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007855Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7856 CXFile File;
7857 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007858 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007859 CXString FileName = clang_getFileName(File);
7860 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7861 clang_disposeString(FileName);
7862 return *this;
7863}
7864
7865Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7866 CXSourceLocation BLoc = clang_getRangeStart(range);
7867 CXSourceLocation ELoc = clang_getRangeEnd(range);
7868
7869 CXFile BFile;
7870 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007871 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007872
7873 CXFile EFile;
7874 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007875 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007876
7877 CXString BFileName = clang_getFileName(BFile);
7878 if (BFile == EFile) {
7879 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7880 BLine, BColumn, ELine, EColumn);
7881 } else {
7882 CXString EFileName = clang_getFileName(EFile);
7883 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7884 BLine, BColumn)
7885 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7886 ELine, EColumn);
7887 clang_disposeString(EFileName);
7888 }
7889 clang_disposeString(BFileName);
7890 return *this;
7891}
7892
7893Logger &cxindex::Logger::operator<<(CXString Str) {
7894 *this << clang_getCString(Str);
7895 return *this;
7896}
7897
7898Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7899 LogOS << Fmt;
7900 return *this;
7901}
7902
Chandler Carruth37ad2582014-06-27 15:14:39 +00007903static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7904
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007905cxindex::Logger::~Logger() {
Chandler Carruth37ad2582014-06-27 15:14:39 +00007906 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007907
7908 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7909
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007910 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007911 OS << "[libclang:" << Name << ':';
7912
Alp Toker1a86ad22014-07-06 06:24:00 +00007913#ifdef USE_DARWIN_THREADS
7914 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007915 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7916 OS << tid << ':';
7917#endif
7918
7919 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7920 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
Yaron Keren09fb7c62015-03-10 07:33:23 +00007921 OS << Msg << '\n';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007922
7923 if (Trace) {
Zachary Turner1fe2a8d2015-03-05 19:15:09 +00007924 llvm::sys::PrintStackTrace(OS);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007925 OS << "--------------------------------------------------\n";
7926 }
7927}